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                 dbg!(&self.used_trappable_imports_opts);
1153                 unused_imports.sort();
1154                 anyhow::bail!("names specified in the `trappable_imports` config option but are not referenced in the target world: {unused_imports:?}");
1155             }
1156         }
1157 
1158         if !self.opts.only_interfaces {
1159             self.build_world_struct(resolve, world)
1160         }
1161 
1162         let imports = mem::take(&mut self.import_interfaces);
1163         self.emit_modules(
1164             imports
1165                 .into_iter()
1166                 .map(|(_, id, module, path)| (id, module, path))
1167                 .collect(),
1168         );
1169 
1170         let exports = mem::take(&mut self.exports.modules);
1171         self.emit_modules(exports);
1172 
1173         let mut src = mem::take(&mut self.src);
1174         if self.opts.rustfmt {
1175             let mut child = Command::new("rustfmt")
1176                 .arg("--edition=2018")
1177                 .stdin(Stdio::piped())
1178                 .stdout(Stdio::piped())
1179                 .spawn()
1180                 .expect("failed to spawn `rustfmt`");
1181             child
1182                 .stdin
1183                 .take()
1184                 .unwrap()
1185                 .write_all(src.as_bytes())
1186                 .unwrap();
1187             src.as_mut_string().truncate(0);
1188             child
1189                 .stdout
1190                 .take()
1191                 .unwrap()
1192                 .read_to_string(src.as_mut_string())
1193                 .unwrap();
1194             let status = child.wait().unwrap();
1195             assert!(status.success());
1196         }
1197 
1198         Ok(src.into())
1199     }
1200 
1201     fn emit_modules(&mut self, modules: Vec<(InterfaceId, String, InterfaceName)>) {
1202         #[derive(Default)]
1203         struct Module {
1204             submodules: BTreeMap<String, Module>,
1205             contents: Vec<String>,
1206         }
1207         let mut map = Module::default();
1208         for (_, module, name) in modules {
1209             let path = match name {
1210                 InterfaceName::Remapped { local_path, .. } => local_path,
1211                 InterfaceName::Path(path) => path,
1212             };
1213             let mut cur = &mut map;
1214             for name in path[..path.len() - 1].iter() {
1215                 cur = cur
1216                     .submodules
1217                     .entry(name.clone())
1218                     .or_insert(Module::default());
1219             }
1220             cur.contents.push(module);
1221         }
1222 
1223         emit(&mut self.src, map);
1224 
1225         fn emit(me: &mut Source, module: Module) {
1226             for (name, submodule) in module.submodules {
1227                 uwriteln!(me, "pub mod {name} {{");
1228                 emit(me, submodule);
1229                 uwriteln!(me, "}}");
1230             }
1231             for submodule in module.contents {
1232                 uwriteln!(me, "{submodule}");
1233             }
1234         }
1235     }
1236 
1237     /// Attempts to find the `key`, possibly with the resource projection
1238     /// `item`, within the `with` map provided to bindings configuration.
1239     fn lookup_replacement(
1240         &mut self,
1241         resolve: &Resolve,
1242         key: &WorldKey,
1243         item: Option<&str>,
1244     ) -> Option<String> {
1245         let item = match item {
1246             Some(item) => LookupItem::Name(item),
1247             None => LookupItem::None,
1248         };
1249 
1250         for (lookup, mut projection) in lookup_keys(resolve, key, item) {
1251             if let Some(renamed) = self.opts.with.get(&lookup) {
1252                 projection.push(renamed.clone());
1253                 projection.reverse();
1254                 self.used_with_opts.insert(lookup);
1255                 return Some(projection.join("::"));
1256             }
1257         }
1258 
1259         None
1260     }
1261 
1262     fn wasmtime_path(&self) -> String {
1263         self.opts
1264             .wasmtime_crate
1265             .clone()
1266             .unwrap_or("wasmtime".to_string())
1267     }
1268 }
1269 
1270 enum LookupItem<'a> {
1271     None,
1272     Name(&'a str),
1273     InterfaceNoPop,
1274 }
1275 
1276 fn lookup_keys(
1277     resolve: &Resolve,
1278     key: &WorldKey,
1279     item: LookupItem<'_>,
1280 ) -> Vec<(String, Vec<String>)> {
1281     struct Name<'a> {
1282         prefix: Prefix,
1283         item: Option<&'a str>,
1284     }
1285 
1286     #[derive(Copy, Clone)]
1287     enum Prefix {
1288         Namespace(PackageId),
1289         UnversionedPackage(PackageId),
1290         VersionedPackage(PackageId),
1291         UnversionedInterface(InterfaceId),
1292         VersionedInterface(InterfaceId),
1293     }
1294 
1295     let prefix = match key {
1296         WorldKey::Interface(id) => Prefix::VersionedInterface(*id),
1297 
1298         // Non-interface-keyed names don't get the lookup logic below,
1299         // they're relatively uncommon so only lookup the precise key here.
1300         WorldKey::Name(key) => {
1301             let to_lookup = match item {
1302                 LookupItem::Name(item) => format!("{key}/{item}"),
1303                 LookupItem::None | LookupItem::InterfaceNoPop => key.to_string(),
1304             };
1305             return vec![(to_lookup, Vec::new())];
1306         }
1307     };
1308 
1309     // Here names are iteratively attempted as `key` + `item` is "walked to
1310     // its root" and each attempt is consulted in `self.opts.with`. This
1311     // loop will start at the leaf, the most specific path, and then walk to
1312     // the root, popping items, trying to find a result.
1313     //
1314     // Each time a name is "popped" the projection from the next path is
1315     // pushed onto `projection`. This means that if we actually find a match
1316     // then `projection` is a collection of namespaces that results in the
1317     // final replacement name.
1318     let (interface_required, item) = match item {
1319         LookupItem::None => (false, None),
1320         LookupItem::Name(s) => (false, Some(s)),
1321         LookupItem::InterfaceNoPop => (true, None),
1322     };
1323     let mut name = Name { prefix, item };
1324     let mut projection = Vec::new();
1325     let mut ret = Vec::new();
1326     loop {
1327         let lookup = name.lookup_key(resolve);
1328         ret.push((lookup, projection.clone()));
1329         if !name.pop(resolve, &mut projection) {
1330             break;
1331         }
1332         if interface_required {
1333             match name.prefix {
1334                 Prefix::VersionedInterface(_) | Prefix::UnversionedInterface(_) => {}
1335                 _ => break,
1336             }
1337         }
1338     }
1339 
1340     return ret;
1341 
1342     impl<'a> Name<'a> {
1343         fn lookup_key(&self, resolve: &Resolve) -> String {
1344             let mut s = self.prefix.lookup_key(resolve);
1345             if let Some(item) = self.item {
1346                 s.push_str("/");
1347                 s.push_str(item);
1348             }
1349             s
1350         }
1351 
1352         fn pop(&mut self, resolve: &'a Resolve, projection: &mut Vec<String>) -> bool {
1353             match (self.item, self.prefix) {
1354                 // If this is a versioned resource name, try the unversioned
1355                 // resource name next.
1356                 (Some(_), Prefix::VersionedInterface(id)) => {
1357                     self.prefix = Prefix::UnversionedInterface(id);
1358                     true
1359                 }
1360                 // If this is an unversioned resource name then time to
1361                 // ignore the resource itself and move on to the next most
1362                 // specific item, versioned interface names.
1363                 (Some(item), Prefix::UnversionedInterface(id)) => {
1364                     self.prefix = Prefix::VersionedInterface(id);
1365                     self.item = None;
1366                     projection.push(item.to_upper_camel_case());
1367                     true
1368                 }
1369                 (Some(_), _) => unreachable!(),
1370                 (None, _) => self.prefix.pop(resolve, projection),
1371             }
1372         }
1373     }
1374 
1375     impl Prefix {
1376         fn lookup_key(&self, resolve: &Resolve) -> String {
1377             match *self {
1378                 Prefix::Namespace(id) => resolve.packages[id].name.namespace.clone(),
1379                 Prefix::UnversionedPackage(id) => {
1380                     let mut name = resolve.packages[id].name.clone();
1381                     name.version = None;
1382                     name.to_string()
1383                 }
1384                 Prefix::VersionedPackage(id) => resolve.packages[id].name.to_string(),
1385                 Prefix::UnversionedInterface(id) => {
1386                     let id = resolve.id_of(id).unwrap();
1387                     match id.find('@') {
1388                         Some(i) => id[..i].to_string(),
1389                         None => id,
1390                     }
1391                 }
1392                 Prefix::VersionedInterface(id) => resolve.id_of(id).unwrap(),
1393             }
1394         }
1395 
1396         fn pop(&mut self, resolve: &Resolve, projection: &mut Vec<String>) -> bool {
1397             *self = match *self {
1398                 // try the unversioned interface next
1399                 Prefix::VersionedInterface(id) => Prefix::UnversionedInterface(id),
1400                 // try this interface's versioned package next
1401                 Prefix::UnversionedInterface(id) => {
1402                     let iface = &resolve.interfaces[id];
1403                     let name = iface.name.as_ref().unwrap();
1404                     projection.push(to_rust_ident(name));
1405                     Prefix::VersionedPackage(iface.package.unwrap())
1406                 }
1407                 // try the unversioned package next
1408                 Prefix::VersionedPackage(id) => Prefix::UnversionedPackage(id),
1409                 // try this package's namespace next
1410                 Prefix::UnversionedPackage(id) => {
1411                     let name = &resolve.packages[id].name;
1412                     projection.push(to_rust_ident(&name.name));
1413                     Prefix::Namespace(id)
1414                 }
1415                 // nothing left to try any more
1416                 Prefix::Namespace(_) => return false,
1417             };
1418             true
1419         }
1420     }
1421 }
1422 
1423 impl Wasmtime {
1424     fn has_world_imports_trait(&self, resolve: &Resolve, world: WorldId) -> bool {
1425         !self.import_functions.is_empty() || get_world_resources(resolve, world).count() > 0
1426     }
1427 
1428     fn world_imports_trait(&mut self, resolve: &Resolve, world: WorldId) {
1429         if !self.has_world_imports_trait(resolve, world) {
1430             return;
1431         }
1432 
1433         let wt = self.wasmtime_path();
1434         let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1435         if let CallStyle::Async = self.opts.call_style() {
1436             uwriteln!(
1437                 self.src,
1438                 "#[{wt}::component::__internal::trait_variant_make(::core::marker::Send)]"
1439             )
1440         }
1441         uwrite!(self.src, "pub trait {world_camel}Imports");
1442         let mut supertraits = vec![];
1443         if let CallStyle::Async = self.opts.call_style() {
1444             supertraits.push("Send".to_string());
1445         }
1446         for (_, name) in get_world_resources(resolve, world) {
1447             supertraits.push(format!("Host{}", name.to_upper_camel_case()));
1448         }
1449         if !supertraits.is_empty() {
1450             uwrite!(self.src, ": {}", supertraits.join(" + "));
1451         }
1452         uwriteln!(self.src, " {{");
1453 
1454         let has_concurrent_function = self.import_functions.iter().any(|func| {
1455             matches!(func.func.kind, FunctionKind::Freestanding)
1456                 && matches!(
1457                     self.opts.import_call_style(None, &func.func.name),
1458                     CallStyle::Concurrent
1459                 )
1460         });
1461 
1462         if has_concurrent_function {
1463             self.src.push_str("type Data;\n");
1464         }
1465 
1466         for f in self.import_functions.iter() {
1467             if let Some(sig) = &f.sig {
1468                 self.src.push_str(sig);
1469                 self.src.push_str(";\n");
1470             }
1471         }
1472         uwriteln!(self.src, "}}");
1473 
1474         let get_host_bounds = if let CallStyle::Concurrent = self.opts.call_style() {
1475             let constraints = world_imports_concurrent_constraints(resolve, world, &self.opts);
1476 
1477             format!("{world_camel}Imports{}", constraints("D"))
1478         } else {
1479             format!("{world_camel}Imports")
1480         };
1481 
1482         uwriteln!(
1483             self.src,
1484             "
1485                 pub trait {world_camel}ImportsGetHost<T, D>:
1486                     Fn(T) -> <Self as {world_camel}ImportsGetHost<T, D>>::Host
1487                         + Send
1488                         + Sync
1489                         + Copy
1490                         + 'static
1491                 {{
1492                     type Host: {get_host_bounds};
1493                 }}
1494 
1495                 impl<F, T, D, O> {world_camel}ImportsGetHost<T, D> for F
1496                 where
1497                     F: Fn(T) -> O + Send + Sync + Copy + 'static,
1498                     O: {get_host_bounds},
1499                 {{
1500                     type Host = O;
1501                 }}
1502             "
1503         );
1504 
1505         // Generate impl WorldImports for &mut WorldImports
1506         let maybe_send = if let CallStyle::Async = self.opts.call_style() {
1507             "+ Send"
1508         } else {
1509             ""
1510         };
1511         if !self.opts.skip_mut_forwarding_impls {
1512             let maybe_maybe_sized = if let CallStyle::Concurrent = self.opts.call_style() {
1513                 ""
1514             } else {
1515                 "+ ?Sized"
1516             };
1517             uwriteln!(
1518                 self.src,
1519                     "impl<_T: {world_camel}Imports {maybe_maybe_sized} {maybe_send}> {world_camel}Imports for &mut _T {{"
1520             );
1521             let has_concurrent_function = self.import_functions.iter().any(|f| {
1522                 matches!(
1523                     self.opts.import_call_style(None, &f.func.name),
1524                     CallStyle::Concurrent
1525                 )
1526             });
1527 
1528             if has_concurrent_function {
1529                 self.src.push_str("type Data = _T::Data;\n");
1530             }
1531             // Forward each method call to &mut T
1532             for f in self.import_functions.iter() {
1533                 if let Some(sig) = &f.sig {
1534                     self.src.push_str(sig);
1535                     let call_style = self.opts.import_call_style(None, &f.func.name);
1536                     if let CallStyle::Concurrent = &call_style {
1537                         uwrite!(
1538                             self.src,
1539                             "{{ <_T as {world_camel}Imports>::{}(store,",
1540                             rust_function_name(&f.func)
1541                         );
1542                     } else {
1543                         uwrite!(
1544                             self.src,
1545                             "{{ {world_camel}Imports::{}(*self,",
1546                             rust_function_name(&f.func)
1547                         );
1548                     }
1549                     for (name, _) in f.func.params.iter() {
1550                         uwrite!(self.src, "{},", to_rust_ident(name));
1551                     }
1552                     uwrite!(self.src, ")");
1553                     if let CallStyle::Async = &call_style {
1554                         uwrite!(self.src, ".await");
1555                     }
1556                     uwriteln!(self.src, "}}");
1557                 }
1558             }
1559             uwriteln!(self.src, "}}");
1560         }
1561     }
1562 
1563     fn import_interface_paths(&self) -> Vec<(InterfaceId, String)> {
1564         self.import_interfaces
1565             .iter()
1566             .map(|(_, id, _, name)| {
1567                 let path = match name {
1568                     InterfaceName::Path(path) => path.join("::"),
1569                     InterfaceName::Remapped { name_at_root, .. } => name_at_root.clone(),
1570                 };
1571                 (*id, path)
1572             })
1573             .collect()
1574     }
1575 
1576     fn import_interface_path(&self, id: &InterfaceId) -> String {
1577         match &self.interface_names[id] {
1578             InterfaceName::Path(path) => path.join("::"),
1579             InterfaceName::Remapped { name_at_root, .. } => name_at_root.clone(),
1580         }
1581     }
1582 
1583     fn world_host_traits(&self, resolve: &Resolve, world: WorldId) -> Vec<String> {
1584         let mut traits = self
1585             .import_interface_paths()
1586             .iter()
1587             .map(|(_, path)| format!("{path}::Host"))
1588             .collect::<Vec<_>>();
1589         if self.has_world_imports_trait(resolve, world) {
1590             let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1591             traits.push(format!("{world_camel}Imports"));
1592         }
1593         if let CallStyle::Async = self.opts.call_style() {
1594             traits.push("Send".to_string());
1595         }
1596         traits
1597     }
1598 
1599     fn world_add_to_linker(&mut self, resolve: &Resolve, world: WorldId) {
1600         let has_world_imports_trait = self.has_world_imports_trait(resolve, world);
1601         if self.import_interfaces.is_empty() && !has_world_imports_trait {
1602             return;
1603         }
1604 
1605         let (options_param, options_arg) = if self.world_link_options.has_any() {
1606             ("options: &LinkOptions,", ", options")
1607         } else {
1608             ("", "")
1609         };
1610 
1611         let camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1612 
1613         let data_bounds = if self.opts.is_store_data_send() {
1614             if let CallStyle::Concurrent = self.opts.call_style() {
1615                 "T: Send + 'static,"
1616             } else {
1617                 "T: Send,"
1618             }
1619         } else {
1620             ""
1621         };
1622         let wt = self.wasmtime_path();
1623         if has_world_imports_trait {
1624             let host_bounds = if let CallStyle::Concurrent = self.opts.call_style() {
1625                 let constraints = world_imports_concurrent_constraints(resolve, world, &self.opts);
1626 
1627                 format!("{camel}Imports{}", constraints("T"))
1628             } else {
1629                 format!("{camel}Imports")
1630             };
1631 
1632             uwrite!(
1633                 self.src,
1634                 "
1635                     pub fn add_to_linker_imports_get_host<
1636                         T,
1637                         G: for<'a> {camel}ImportsGetHost<&'a mut T, T, Host: {host_bounds}>
1638                     >(
1639                         linker: &mut {wt}::component::Linker<T>,
1640                         {options_param}
1641                         host_getter: G,
1642                     ) -> {wt}::Result<()>
1643                         where {data_bounds}
1644                     {{
1645                         let mut linker = linker.root();
1646                 "
1647             );
1648             let gate = FeatureGate::open(&mut self.src, &resolve.worlds[world].stability);
1649             for (ty, name) in get_world_resources(resolve, world) {
1650                 Self::generate_add_resource_to_linker(
1651                     None,
1652                     &mut self.src,
1653                     &self.opts,
1654                     &wt,
1655                     "linker",
1656                     name,
1657                     &resolve.types[ty].stability,
1658                 );
1659             }
1660             for f in self.import_functions.iter() {
1661                 self.src.push_str(&f.add_to_linker);
1662                 self.src.push_str("\n");
1663             }
1664             gate.close(&mut self.src);
1665             uwriteln!(self.src, "Ok(())\n}}");
1666         }
1667 
1668         let (host_bounds, data_bounds) = if let CallStyle::Concurrent = self.opts.call_style() {
1669             let bounds = self
1670                 .import_interfaces
1671                 .iter()
1672                 .map(|(key, id, _, name)| {
1673                     (
1674                         key,
1675                         id,
1676                         match name {
1677                             InterfaceName::Path(path) => path.join("::"),
1678                             InterfaceName::Remapped { name_at_root, .. } => name_at_root.clone(),
1679                         },
1680                     )
1681                 })
1682                 .map(|(key, id, path)| {
1683                     format!(
1684                         " + {path}::Host{}",
1685                         concurrent_constraints(
1686                             resolve,
1687                             &self.opts,
1688                             Some(&resolve.name_world_key(key)),
1689                             *id
1690                         )("T")
1691                     )
1692                 })
1693                 .chain(if self.has_world_imports_trait(resolve, world) {
1694                     let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1695                     let constraints =
1696                         world_imports_concurrent_constraints(resolve, world, &self.opts);
1697                     Some(format!(" + {world_camel}Imports{}", constraints("T")))
1698                 } else {
1699                     None
1700                 })
1701                 .collect::<Vec<_>>()
1702                 .concat();
1703 
1704             (
1705                 format!("U: Send{bounds}"),
1706                 format!("T: Send{bounds} + 'static,"),
1707             )
1708         } else {
1709             (
1710                 format!("U: {}", self.world_host_traits(resolve, world).join(" + ")),
1711                 data_bounds.to_string(),
1712             )
1713         };
1714 
1715         if !self.opts.skip_mut_forwarding_impls {
1716             uwriteln!(
1717                 self.src,
1718                 "
1719                     pub fn add_to_linker<T, U>(
1720                         linker: &mut {wt}::component::Linker<T>,
1721                         {options_param}
1722                         get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
1723                     ) -> {wt}::Result<()>
1724                         where
1725                             {data_bounds}
1726                             {host_bounds}
1727                     {{
1728                 "
1729             );
1730             let gate = FeatureGate::open(&mut self.src, &resolve.worlds[world].stability);
1731             if has_world_imports_trait {
1732                 uwriteln!(
1733                     self.src,
1734                     "Self::add_to_linker_imports_get_host(linker {options_arg}, get)?;"
1735                 );
1736             }
1737             for (interface_id, path) in self.import_interface_paths() {
1738                 let options_arg = if self.interface_link_options[&interface_id].has_any() {
1739                     ", &options.into()"
1740                 } else {
1741                     ""
1742                 };
1743 
1744                 let import_stability = resolve.worlds[world]
1745                     .imports
1746                     .iter()
1747                     .filter_map(|(_, i)| match i {
1748                         WorldItem::Interface { id, stability } if *id == interface_id => {
1749                             Some(stability.clone())
1750                         }
1751                         _ => None,
1752                     })
1753                     .next()
1754                     .unwrap_or(Stability::Unknown);
1755 
1756                 let gate = FeatureGate::open(&mut self.src, &import_stability);
1757                 uwriteln!(
1758                     self.src,
1759                     "{path}::add_to_linker(linker {options_arg}, get)?;"
1760                 );
1761                 gate.close(&mut self.src);
1762             }
1763             gate.close(&mut self.src);
1764             uwriteln!(self.src, "Ok(())\n}}");
1765         }
1766     }
1767 
1768     fn generate_add_resource_to_linker(
1769         qualifier: Option<&str>,
1770         src: &mut Source,
1771         opts: &Opts,
1772         wt: &str,
1773         inst: &str,
1774         name: &str,
1775         stability: &Stability,
1776     ) {
1777         let gate = FeatureGate::open(src, stability);
1778         let camel = name.to_upper_camel_case();
1779         if let CallStyle::Async = opts.drop_call_style(qualifier, name) {
1780             uwriteln!(
1781                 src,
1782                 "{inst}.resource_async(
1783                     \"{name}\",
1784                     {wt}::component::ResourceType::host::<{camel}>(),
1785                     move |mut store, rep| {{
1786                         {wt}::component::__internal::Box::new(async move {{
1787                             Host{camel}::drop(&mut host_getter(store.data_mut()), {wt}::component::Resource::new_own(rep)).await
1788                         }})
1789                     }},
1790                 )?;"
1791             )
1792         } else {
1793             uwriteln!(
1794                 src,
1795                 "{inst}.resource(
1796                     \"{name}\",
1797                     {wt}::component::ResourceType::host::<{camel}>(),
1798                     move |mut store, rep| -> {wt}::Result<()> {{
1799                         Host{camel}::drop(&mut host_getter(store.data_mut()), {wt}::component::Resource::new_own(rep))
1800                     }},
1801                 )?;"
1802             )
1803         }
1804         gate.close(src);
1805     }
1806 }
1807 
1808 struct InterfaceGenerator<'a> {
1809     src: Source,
1810     generator: &'a mut Wasmtime,
1811     resolve: &'a Resolve,
1812     current_interface: Option<(InterfaceId, &'a WorldKey, bool)>,
1813 }
1814 
1815 impl<'a> InterfaceGenerator<'a> {
1816     fn new(generator: &'a mut Wasmtime, resolve: &'a Resolve) -> InterfaceGenerator<'a> {
1817         InterfaceGenerator {
1818             src: Source::default(),
1819             generator,
1820             resolve,
1821             current_interface: None,
1822         }
1823     }
1824 
1825     fn types_imported(&self) -> bool {
1826         match self.current_interface {
1827             Some((_, _, is_export)) => !is_export,
1828             None => true,
1829         }
1830     }
1831 
1832     fn types(&mut self, id: InterfaceId) {
1833         for (name, id) in self.resolve.interfaces[id].types.iter() {
1834             self.define_type(name, *id);
1835         }
1836     }
1837 
1838     fn define_type(&mut self, name: &str, id: TypeId) {
1839         let ty = &self.resolve.types[id];
1840         match &ty.kind {
1841             TypeDefKind::Record(record) => self.type_record(id, name, record, &ty.docs),
1842             TypeDefKind::Flags(flags) => self.type_flags(id, name, flags, &ty.docs),
1843             TypeDefKind::Tuple(tuple) => self.type_tuple(id, name, tuple, &ty.docs),
1844             TypeDefKind::Enum(enum_) => self.type_enum(id, name, enum_, &ty.docs),
1845             TypeDefKind::Variant(variant) => self.type_variant(id, name, variant, &ty.docs),
1846             TypeDefKind::Option(t) => self.type_option(id, name, t, &ty.docs),
1847             TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
1848             TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
1849             TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
1850             TypeDefKind::Future(t) => self.type_future(id, name, t.as_ref(), &ty.docs),
1851             TypeDefKind::Stream(t) => self.type_stream(id, name, t.as_ref(), &ty.docs),
1852             TypeDefKind::ErrorContext => self.type_error_context(id, name, &ty.docs),
1853             TypeDefKind::Handle(handle) => self.type_handle(id, name, handle, &ty.docs),
1854             TypeDefKind::Resource => self.type_resource(id, name, ty, &ty.docs),
1855             TypeDefKind::Unknown => unreachable!(),
1856         }
1857     }
1858 
1859     fn type_handle(&mut self, id: TypeId, name: &str, handle: &Handle, docs: &Docs) {
1860         self.rustdoc(docs);
1861         let name = name.to_upper_camel_case();
1862         uwriteln!(self.src, "pub type {name} = ");
1863         self.print_handle(handle);
1864         self.push_str(";\n");
1865         self.assert_type(id, &name);
1866     }
1867 
1868     fn type_resource(&mut self, id: TypeId, name: &str, resource: &TypeDef, docs: &Docs) {
1869         let camel = name.to_upper_camel_case();
1870         let wt = self.generator.wasmtime_path();
1871 
1872         if self.types_imported() {
1873             self.rustdoc(docs);
1874 
1875             let replacement = match self.current_interface {
1876                 Some((_, key, _)) => {
1877                     self.generator
1878                         .lookup_replacement(self.resolve, key, Some(name))
1879                 }
1880                 None => {
1881                     self.generator.used_with_opts.insert(name.into());
1882                     self.generator.opts.with.get(name).cloned()
1883                 }
1884             };
1885             match replacement {
1886                 Some(path) => {
1887                     uwriteln!(
1888                         self.src,
1889                         "pub use {}{path} as {camel};",
1890                         self.path_to_root()
1891                     );
1892                 }
1893                 None => {
1894                     uwriteln!(self.src, "pub enum {camel} {{}}");
1895                 }
1896             }
1897 
1898             // Generate resource trait
1899             if let CallStyle::Async = self.generator.opts.call_style() {
1900                 uwriteln!(
1901                     self.src,
1902                     "#[{wt}::component::__internal::trait_variant_make(::core::marker::Send)]"
1903                 )
1904             }
1905 
1906             uwriteln!(self.src, "pub trait Host{camel}: Sized {{");
1907 
1908             let mut functions = match resource.owner {
1909                 TypeOwner::World(id) => self.resolve.worlds[id]
1910                     .imports
1911                     .values()
1912                     .filter_map(|item| match item {
1913                         WorldItem::Function(f) => Some(f),
1914                         _ => None,
1915                     })
1916                     .collect(),
1917                 TypeOwner::Interface(id) => self.resolve.interfaces[id]
1918                     .functions
1919                     .values()
1920                     .collect::<Vec<_>>(),
1921                 TypeOwner::None => {
1922                     panic!("A resource must be owned by a world or interface");
1923                 }
1924             };
1925 
1926             functions.retain(|func| match func.kind {
1927                 FunctionKind::Freestanding => false,
1928                 FunctionKind::Method(resource)
1929                 | FunctionKind::Static(resource)
1930                 | FunctionKind::Constructor(resource) => id == resource,
1931             });
1932 
1933             let has_concurrent_function = functions.iter().any(|func| {
1934                 matches!(
1935                     self.generator
1936                         .opts
1937                         .import_call_style(self.qualifier().as_deref(), &func.name),
1938                     CallStyle::Concurrent
1939                 )
1940             });
1941 
1942             if has_concurrent_function {
1943                 uwriteln!(self.src, "type {camel}Data;");
1944             }
1945 
1946             for func in &functions {
1947                 self.generate_function_trait_sig(func, &format!("{camel}Data"));
1948                 self.push_str(";\n");
1949             }
1950 
1951             if let CallStyle::Async = self
1952                 .generator
1953                 .opts
1954                 .drop_call_style(self.qualifier().as_deref(), name)
1955             {
1956                 uwrite!(self.src, "async ");
1957             }
1958             uwrite!(
1959                 self.src,
1960                 "fn drop(&mut self, rep: {wt}::component::Resource<{camel}>) -> {wt}::Result<()>;"
1961             );
1962 
1963             uwriteln!(self.src, "}}");
1964 
1965             // Generate impl HostResource for &mut HostResource
1966             if !self.generator.opts.skip_mut_forwarding_impls {
1967                 let maybe_send = if let CallStyle::Async = self.generator.opts.call_style() {
1968                     "+ Send"
1969                 } else {
1970                     ""
1971                 };
1972                 let maybe_maybe_sized = if has_concurrent_function {
1973                     ""
1974                 } else {
1975                     "+ ?Sized"
1976                 };
1977                 uwriteln!(
1978                     self.src,
1979                     "impl <_T: Host{camel} {maybe_maybe_sized} {maybe_send}> Host{camel} for &mut _T {{"
1980                 );
1981                 if has_concurrent_function {
1982                     uwriteln!(self.src, "type {camel}Data = _T::{camel}Data;");
1983                 }
1984                 for func in &functions {
1985                     let call_style = self
1986                         .generator
1987                         .opts
1988                         .import_call_style(self.qualifier().as_deref(), &func.name);
1989                     self.generate_function_trait_sig(func, &format!("{camel}Data"));
1990                     if let CallStyle::Concurrent = call_style {
1991                         uwrite!(
1992                             self.src,
1993                             "{{ <_T as Host{camel}>::{}(store,",
1994                             rust_function_name(func)
1995                         );
1996                     } else {
1997                         uwrite!(
1998                             self.src,
1999                             "{{ Host{camel}::{}(*self,",
2000                             rust_function_name(func)
2001                         );
2002                     }
2003                     for (name, _) in func.params.iter() {
2004                         uwrite!(self.src, "{},", to_rust_ident(name));
2005                     }
2006                     uwrite!(self.src, ")");
2007                     if let CallStyle::Async = call_style {
2008                         uwrite!(self.src, ".await");
2009                     }
2010                     uwriteln!(self.src, "}}");
2011                 }
2012                 if let CallStyle::Async = self
2013                     .generator
2014                     .opts
2015                     .drop_call_style(self.qualifier().as_deref(), name)
2016                 {
2017                     uwriteln!(self.src, "
2018                         async fn drop(&mut self, rep: {wt}::component::Resource<{camel}>) -> {wt}::Result<()> {{
2019                             Host{camel}::drop(*self, rep).await
2020                         }}",
2021                     );
2022                 } else {
2023                     uwriteln!(self.src, "
2024                         fn drop(&mut self, rep: {wt}::component::Resource<{camel}>) -> {wt}::Result<()> {{
2025                             Host{camel}::drop(*self, rep)
2026                         }}",
2027                     );
2028                 }
2029                 uwriteln!(self.src, "}}");
2030             }
2031         } else {
2032             self.rustdoc(docs);
2033             uwriteln!(
2034                 self.src,
2035                 "
2036                     pub type {camel} = {wt}::component::ResourceAny;
2037 
2038                     pub struct Guest{camel}<'a> {{
2039                         funcs: &'a Guest,
2040                     }}
2041                 "
2042             );
2043         }
2044     }
2045 
2046     fn type_record(&mut self, id: TypeId, _name: &str, record: &Record, docs: &Docs) {
2047         let info = self.info(id);
2048         let wt = self.generator.wasmtime_path();
2049 
2050         // We use a BTree set to make sure we don't have any duplicates and we have a stable order
2051         let additional_derives: BTreeSet<String> = self
2052             .generator
2053             .opts
2054             .additional_derive_attributes
2055             .iter()
2056             .cloned()
2057             .collect();
2058 
2059         for (name, mode) in self.modes_of(id) {
2060             let lt = self.lifetime_for(&info, mode);
2061             self.rustdoc(docs);
2062 
2063             let mut derives = additional_derives.clone();
2064 
2065             uwriteln!(self.src, "#[derive({wt}::component::ComponentType)]");
2066             if lt.is_none() {
2067                 uwriteln!(self.src, "#[derive({wt}::component::Lift)]");
2068             }
2069             uwriteln!(self.src, "#[derive({wt}::component::Lower)]");
2070             self.push_str("#[component(record)]\n");
2071             if let Some(path) = &self.generator.opts.wasmtime_crate {
2072                 uwriteln!(self.src, "#[component(wasmtime_crate = {path})]\n");
2073             }
2074 
2075             if info.is_copy() {
2076                 derives.extend(["Copy", "Clone"].into_iter().map(|s| s.to_string()));
2077             } else if info.is_clone() {
2078                 derives.insert("Clone".to_string());
2079             }
2080 
2081             if !derives.is_empty() {
2082                 self.push_str("#[derive(");
2083                 self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
2084                 self.push_str(")]\n")
2085             }
2086 
2087             self.push_str(&format!("pub struct {name}"));
2088             self.print_generics(lt);
2089             self.push_str(" {\n");
2090             for field in record.fields.iter() {
2091                 self.rustdoc(&field.docs);
2092                 self.push_str(&format!("#[component(name = \"{}\")]\n", field.name));
2093                 self.push_str("pub ");
2094                 self.push_str(&to_rust_ident(&field.name));
2095                 self.push_str(": ");
2096                 self.print_ty(&field.ty, mode);
2097                 self.push_str(",\n");
2098             }
2099             self.push_str("}\n");
2100 
2101             self.push_str("impl");
2102             self.print_generics(lt);
2103             self.push_str(" core::fmt::Debug for ");
2104             self.push_str(&name);
2105             self.print_generics(lt);
2106             self.push_str(" {\n");
2107             self.push_str(
2108                 "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2109             );
2110             self.push_str(&format!("f.debug_struct(\"{name}\")"));
2111             for field in record.fields.iter() {
2112                 self.push_str(&format!(
2113                     ".field(\"{}\", &self.{})",
2114                     field.name,
2115                     to_rust_ident(&field.name)
2116                 ));
2117             }
2118             self.push_str(".finish()\n");
2119             self.push_str("}\n");
2120             self.push_str("}\n");
2121 
2122             if info.error {
2123                 self.push_str("impl");
2124                 self.print_generics(lt);
2125                 self.push_str(" core::fmt::Display for ");
2126                 self.push_str(&name);
2127                 self.print_generics(lt);
2128                 self.push_str(" {\n");
2129                 self.push_str(
2130                     "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2131                 );
2132                 self.push_str("write!(f, \"{:?}\", self)\n");
2133                 self.push_str("}\n");
2134                 self.push_str("}\n");
2135 
2136                 self.push_str("impl core::error::Error for ");
2137                 self.push_str(&name);
2138                 self.push_str("{}\n");
2139             }
2140             self.assert_type(id, &name);
2141         }
2142     }
2143 
2144     fn type_tuple(&mut self, id: TypeId, _name: &str, tuple: &Tuple, docs: &Docs) {
2145         let info = self.info(id);
2146         for (name, mode) in self.modes_of(id) {
2147             let lt = self.lifetime_for(&info, mode);
2148             self.rustdoc(docs);
2149             self.push_str(&format!("pub type {name}"));
2150             self.print_generics(lt);
2151             self.push_str(" = (");
2152             for ty in tuple.types.iter() {
2153                 self.print_ty(ty, mode);
2154                 self.push_str(",");
2155             }
2156             self.push_str(");\n");
2157             self.assert_type(id, &name);
2158         }
2159     }
2160 
2161     fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
2162         self.rustdoc(docs);
2163         let wt = self.generator.wasmtime_path();
2164         let rust_name = to_rust_upper_camel_case(name);
2165         uwriteln!(self.src, "{wt}::component::flags!(\n");
2166         self.src.push_str(&format!("{rust_name} {{\n"));
2167         for flag in flags.flags.iter() {
2168             // TODO wasmtime-component-macro doesn't support docs for flags rn
2169             uwrite!(
2170                 self.src,
2171                 "#[component(name=\"{}\")] const {};\n",
2172                 flag.name,
2173                 flag.name.to_shouty_snake_case()
2174             );
2175         }
2176         self.src.push_str("}\n");
2177         self.src.push_str(");\n\n");
2178         self.assert_type(id, &rust_name);
2179     }
2180 
2181     fn type_variant(&mut self, id: TypeId, _name: &str, variant: &Variant, docs: &Docs) {
2182         self.print_rust_enum(
2183             id,
2184             variant.cases.iter().map(|c| {
2185                 (
2186                     c.name.to_upper_camel_case(),
2187                     Some(c.name.clone()),
2188                     &c.docs,
2189                     c.ty.as_ref(),
2190                 )
2191             }),
2192             docs,
2193             "variant",
2194         );
2195     }
2196 
2197     fn type_option(&mut self, id: TypeId, _name: &str, payload: &Type, docs: &Docs) {
2198         let info = self.info(id);
2199 
2200         for (name, mode) in self.modes_of(id) {
2201             self.rustdoc(docs);
2202             let lt = self.lifetime_for(&info, mode);
2203             self.push_str(&format!("pub type {name}"));
2204             self.print_generics(lt);
2205             self.push_str("= Option<");
2206             self.print_ty(payload, mode);
2207             self.push_str(">;\n");
2208             self.assert_type(id, &name);
2209         }
2210     }
2211 
2212     // Emit a double-check that the wit-parser-understood size of a type agrees
2213     // with the Wasmtime-understood size of a type.
2214     fn assert_type(&mut self, id: TypeId, name: &str) {
2215         self.push_str("const _: () = {\n");
2216         let wt = self.generator.wasmtime_path();
2217         uwriteln!(
2218             self.src,
2219             "assert!({} == <{name} as {wt}::component::ComponentType>::SIZE32);",
2220             self.generator.sizes.size(&Type::Id(id)).size_wasm32(),
2221         );
2222         uwriteln!(
2223             self.src,
2224             "assert!({} == <{name} as {wt}::component::ComponentType>::ALIGN32);",
2225             self.generator.sizes.align(&Type::Id(id)).align_wasm32(),
2226         );
2227         self.push_str("};\n");
2228     }
2229 
2230     fn print_rust_enum<'b>(
2231         &mut self,
2232         id: TypeId,
2233         cases: impl IntoIterator<Item = (String, Option<String>, &'b Docs, Option<&'b Type>)> + Clone,
2234         docs: &Docs,
2235         derive_component: &str,
2236     ) where
2237         Self: Sized,
2238     {
2239         let info = self.info(id);
2240         let wt = self.generator.wasmtime_path();
2241 
2242         // We use a BTree set to make sure we don't have any duplicates and we have a stable order
2243         let additional_derives: BTreeSet<String> = self
2244             .generator
2245             .opts
2246             .additional_derive_attributes
2247             .iter()
2248             .cloned()
2249             .collect();
2250 
2251         for (name, mode) in self.modes_of(id) {
2252             let name = to_rust_upper_camel_case(&name);
2253 
2254             let mut derives = additional_derives.clone();
2255 
2256             self.rustdoc(docs);
2257             let lt = self.lifetime_for(&info, mode);
2258             uwriteln!(self.src, "#[derive({wt}::component::ComponentType)]");
2259             if lt.is_none() {
2260                 uwriteln!(self.src, "#[derive({wt}::component::Lift)]");
2261             }
2262             uwriteln!(self.src, "#[derive({wt}::component::Lower)]");
2263             self.push_str(&format!("#[component({derive_component})]\n"));
2264             if let Some(path) = &self.generator.opts.wasmtime_crate {
2265                 uwriteln!(self.src, "#[component(wasmtime_crate = {path})]\n");
2266             }
2267             if info.is_copy() {
2268                 derives.extend(["Copy", "Clone"].into_iter().map(|s| s.to_string()));
2269             } else if info.is_clone() {
2270                 derives.insert("Clone".to_string());
2271             }
2272 
2273             if !derives.is_empty() {
2274                 self.push_str("#[derive(");
2275                 self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
2276                 self.push_str(")]\n")
2277             }
2278 
2279             self.push_str(&format!("pub enum {name}"));
2280             self.print_generics(lt);
2281             self.push_str("{\n");
2282             for (case_name, component_name, docs, payload) in cases.clone() {
2283                 self.rustdoc(docs);
2284                 if let Some(n) = component_name {
2285                     self.push_str(&format!("#[component(name = \"{n}\")] "));
2286                 }
2287                 self.push_str(&case_name);
2288                 if let Some(ty) = payload {
2289                     self.push_str("(");
2290                     self.print_ty(ty, mode);
2291                     self.push_str(")")
2292                 }
2293                 self.push_str(",\n");
2294             }
2295             self.push_str("}\n");
2296 
2297             self.print_rust_enum_debug(
2298                 id,
2299                 mode,
2300                 &name,
2301                 cases
2302                     .clone()
2303                     .into_iter()
2304                     .map(|(name, _attr, _docs, ty)| (name, ty)),
2305             );
2306 
2307             if info.error {
2308                 self.push_str("impl");
2309                 self.print_generics(lt);
2310                 self.push_str(" core::fmt::Display for ");
2311                 self.push_str(&name);
2312                 self.print_generics(lt);
2313                 self.push_str(" {\n");
2314                 self.push_str(
2315                     "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2316                 );
2317                 self.push_str("write!(f, \"{:?}\", self)\n");
2318                 self.push_str("}\n");
2319                 self.push_str("}\n");
2320 
2321                 self.push_str("impl");
2322                 self.print_generics(lt);
2323                 self.push_str(" core::error::Error for ");
2324                 self.push_str(&name);
2325                 self.print_generics(lt);
2326                 self.push_str(" {}\n");
2327             }
2328 
2329             self.assert_type(id, &name);
2330         }
2331     }
2332 
2333     fn print_rust_enum_debug<'b>(
2334         &mut self,
2335         id: TypeId,
2336         mode: TypeMode,
2337         name: &str,
2338         cases: impl IntoIterator<Item = (String, Option<&'b Type>)>,
2339     ) where
2340         Self: Sized,
2341     {
2342         let info = self.info(id);
2343         let lt = self.lifetime_for(&info, mode);
2344         self.push_str("impl");
2345         self.print_generics(lt);
2346         self.push_str(" core::fmt::Debug for ");
2347         self.push_str(name);
2348         self.print_generics(lt);
2349         self.push_str(" {\n");
2350         self.push_str("fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n");
2351         self.push_str("match self {\n");
2352         for (case_name, payload) in cases {
2353             self.push_str(name);
2354             self.push_str("::");
2355             self.push_str(&case_name);
2356             if payload.is_some() {
2357                 self.push_str("(e)");
2358             }
2359             self.push_str(" => {\n");
2360             self.push_str(&format!("f.debug_tuple(\"{name}::{case_name}\")"));
2361             if payload.is_some() {
2362                 self.push_str(".field(e)");
2363             }
2364             self.push_str(".finish()\n");
2365             self.push_str("}\n");
2366         }
2367         self.push_str("}\n");
2368         self.push_str("}\n");
2369         self.push_str("}\n");
2370     }
2371 
2372     fn type_result(&mut self, id: TypeId, _name: &str, result: &Result_, docs: &Docs) {
2373         let info = self.info(id);
2374 
2375         for (name, mode) in self.modes_of(id) {
2376             self.rustdoc(docs);
2377             let lt = self.lifetime_for(&info, mode);
2378             self.push_str(&format!("pub type {name}"));
2379             self.print_generics(lt);
2380             self.push_str("= Result<");
2381             self.print_optional_ty(result.ok.as_ref(), mode);
2382             self.push_str(",");
2383             self.print_optional_ty(result.err.as_ref(), mode);
2384             self.push_str(">;\n");
2385             self.assert_type(id, &name);
2386         }
2387     }
2388 
2389     fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
2390         let info = self.info(id);
2391         let wt = self.generator.wasmtime_path();
2392 
2393         // We use a BTree set to make sure we don't have any duplicates and have a stable order
2394         let mut derives: BTreeSet<String> = self
2395             .generator
2396             .opts
2397             .additional_derive_attributes
2398             .iter()
2399             .cloned()
2400             .collect();
2401 
2402         derives.extend(
2403             ["Clone", "Copy", "PartialEq", "Eq"]
2404                 .into_iter()
2405                 .map(|s| s.to_string()),
2406         );
2407 
2408         let name = to_rust_upper_camel_case(name);
2409         self.rustdoc(docs);
2410         uwriteln!(self.src, "#[derive({wt}::component::ComponentType)]");
2411         uwriteln!(self.src, "#[derive({wt}::component::Lift)]");
2412         uwriteln!(self.src, "#[derive({wt}::component::Lower)]");
2413         self.push_str("#[component(enum)]\n");
2414         if let Some(path) = &self.generator.opts.wasmtime_crate {
2415             uwriteln!(self.src, "#[component(wasmtime_crate = {path})]\n");
2416         }
2417 
2418         self.push_str("#[derive(");
2419         self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
2420         self.push_str(")]\n");
2421 
2422         let repr = match enum_.cases.len().ilog2() {
2423             0..=7 => "u8",
2424             8..=15 => "u16",
2425             _ => "u32",
2426         };
2427         uwriteln!(self.src, "#[repr({repr})]");
2428 
2429         self.push_str(&format!("pub enum {name} {{\n"));
2430         for case in enum_.cases.iter() {
2431             self.rustdoc(&case.docs);
2432             self.push_str(&format!("#[component(name = \"{}\")]", case.name));
2433             self.push_str(&case.name.to_upper_camel_case());
2434             self.push_str(",\n");
2435         }
2436         self.push_str("}\n");
2437 
2438         // Auto-synthesize an implementation of the standard `Error` trait for
2439         // error-looking types based on their name.
2440         if info.error {
2441             self.push_str("impl ");
2442             self.push_str(&name);
2443             self.push_str("{\n");
2444 
2445             self.push_str("pub fn name(&self) -> &'static str {\n");
2446             self.push_str("match self {\n");
2447             for case in enum_.cases.iter() {
2448                 self.push_str(&name);
2449                 self.push_str("::");
2450                 self.push_str(&case.name.to_upper_camel_case());
2451                 self.push_str(" => \"");
2452                 self.push_str(case.name.as_str());
2453                 self.push_str("\",\n");
2454             }
2455             self.push_str("}\n");
2456             self.push_str("}\n");
2457 
2458             self.push_str("pub fn message(&self) -> &'static str {\n");
2459             self.push_str("match self {\n");
2460             for case in enum_.cases.iter() {
2461                 self.push_str(&name);
2462                 self.push_str("::");
2463                 self.push_str(&case.name.to_upper_camel_case());
2464                 self.push_str(" => \"");
2465                 if let Some(contents) = &case.docs.contents {
2466                     self.push_str(contents.trim());
2467                 }
2468                 self.push_str("\",\n");
2469             }
2470             self.push_str("}\n");
2471             self.push_str("}\n");
2472 
2473             self.push_str("}\n");
2474 
2475             self.push_str("impl core::fmt::Debug for ");
2476             self.push_str(&name);
2477             self.push_str(
2478                 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2479             );
2480             self.push_str("f.debug_struct(\"");
2481             self.push_str(&name);
2482             self.push_str("\")\n");
2483             self.push_str(".field(\"code\", &(*self as i32))\n");
2484             self.push_str(".field(\"name\", &self.name())\n");
2485             self.push_str(".field(\"message\", &self.message())\n");
2486             self.push_str(".finish()\n");
2487             self.push_str("}\n");
2488             self.push_str("}\n");
2489 
2490             self.push_str("impl core::fmt::Display for ");
2491             self.push_str(&name);
2492             self.push_str(
2493                 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2494             );
2495             self.push_str("write!(f, \"{} (error {})\", self.name(), *self as i32)");
2496             self.push_str("}\n");
2497             self.push_str("}\n");
2498             self.push_str("\n");
2499             self.push_str("impl core::error::Error for ");
2500             self.push_str(&name);
2501             self.push_str("{}\n");
2502         } else {
2503             self.print_rust_enum_debug(
2504                 id,
2505                 TypeMode::Owned,
2506                 &name,
2507                 enum_
2508                     .cases
2509                     .iter()
2510                     .map(|c| (c.name.to_upper_camel_case(), None)),
2511             )
2512         }
2513         self.assert_type(id, &name);
2514     }
2515 
2516     fn type_alias(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
2517         let info = self.info(id);
2518         for (name, mode) in self.modes_of(id) {
2519             self.rustdoc(docs);
2520             self.push_str(&format!("pub type {name}"));
2521             let lt = self.lifetime_for(&info, mode);
2522             self.print_generics(lt);
2523             self.push_str(" = ");
2524             self.print_ty(ty, mode);
2525             self.push_str(";\n");
2526             let def_id = resolve_type_definition_id(self.resolve, id);
2527             if !matches!(self.resolve().types[def_id].kind, TypeDefKind::Resource) {
2528                 self.assert_type(id, &name);
2529             }
2530         }
2531     }
2532 
2533     fn type_list(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
2534         let info = self.info(id);
2535         for (name, mode) in self.modes_of(id) {
2536             let lt = self.lifetime_for(&info, mode);
2537             self.rustdoc(docs);
2538             self.push_str(&format!("pub type {name}"));
2539             self.print_generics(lt);
2540             self.push_str(" = ");
2541             self.print_list(ty, mode);
2542             self.push_str(";\n");
2543             self.assert_type(id, &name);
2544         }
2545     }
2546 
2547     fn type_stream(&mut self, id: TypeId, name: &str, ty: Option<&Type>, docs: &Docs) {
2548         self.rustdoc(docs);
2549         self.push_str(&format!("pub type {name}"));
2550         self.print_generics(None);
2551         self.push_str(" = ");
2552         self.print_stream(ty);
2553         self.push_str(";\n");
2554         self.assert_type(id, &name);
2555     }
2556 
2557     fn type_future(&mut self, id: TypeId, name: &str, ty: Option<&Type>, docs: &Docs) {
2558         self.rustdoc(docs);
2559         self.push_str(&format!("pub type {name}"));
2560         self.print_generics(None);
2561         self.push_str(" = ");
2562         self.print_future(ty);
2563         self.push_str(";\n");
2564         self.assert_type(id, &name);
2565     }
2566 
2567     fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
2568         self.rustdoc(docs);
2569         self.push_str(&format!("pub type {name}"));
2570         self.push_str(" = ");
2571         self.print_error_context();
2572         self.push_str(";\n");
2573         self.assert_type(id, &name);
2574     }
2575 
2576     fn print_result_ty(&mut self, result: Option<Type>, mode: TypeMode) {
2577         match result {
2578             Some(ty) => self.print_ty(&ty, mode),
2579             None => self.push_str("()"),
2580         }
2581     }
2582 
2583     fn print_result_ty_tuple(&mut self, result: Option<Type>, mode: TypeMode) {
2584         self.push_str("(");
2585         if let Some(ty) = result {
2586             self.print_ty(&ty, mode);
2587             self.push_str(",");
2588         }
2589         self.push_str(")");
2590     }
2591 
2592     fn special_case_trappable_error(
2593         &mut self,
2594         func: &Function,
2595     ) -> Option<(&'a Result_, TypeId, String)> {
2596         self.generator
2597             .used_trappable_imports_opts
2598             .insert(func.name.clone());
2599 
2600         let result = func.result?;
2601 
2602         // We fillin a special trappable error type in the case when a function has just one
2603         // result, which is itself a `result<a, e>`, and the `e` is *not* a primitive
2604         // (i.e. defined in std) type, and matches the typename given by the user.
2605         let id = match result {
2606             Type::Id(id) => id,
2607             _ => return None,
2608         };
2609         let result = match &self.resolve.types[id].kind {
2610             TypeDefKind::Result(r) => r,
2611             _ => return None,
2612         };
2613         let error_typeid = match result.err? {
2614             Type::Id(id) => resolve_type_definition_id(&self.resolve, id),
2615             _ => return None,
2616         };
2617 
2618         let name = self.generator.trappable_errors.get(&error_typeid)?;
2619 
2620         let mut path = self.path_to_root();
2621         uwrite!(path, "{name}");
2622         Some((result, error_typeid, path))
2623     }
2624 
2625     fn generate_add_to_linker(&mut self, id: InterfaceId, name: &str) {
2626         let iface = &self.resolve.interfaces[id];
2627         let owner = TypeOwner::Interface(id);
2628         let wt = self.generator.wasmtime_path();
2629 
2630         let is_maybe_async = matches!(self.generator.opts.call_style(), CallStyle::Async);
2631         if is_maybe_async {
2632             uwriteln!(
2633                 self.src,
2634                 "#[{wt}::component::__internal::trait_variant_make(::core::marker::Send)]"
2635             )
2636         }
2637         // Generate the `pub trait` which represents the host functionality for
2638         // this import which additionally inherits from all resource traits
2639         // for this interface defined by `type_resource`.
2640 
2641         uwrite!(self.src, "pub trait Host");
2642         let mut host_supertraits = vec![];
2643         if is_maybe_async {
2644             host_supertraits.push("Send".to_string());
2645         }
2646         let mut saw_resources = false;
2647         for (_, name) in get_resources(self.resolve, id) {
2648             saw_resources = true;
2649             host_supertraits.push(format!("Host{}", name.to_upper_camel_case()));
2650         }
2651         if saw_resources {
2652             host_supertraits.push("Sized".to_string());
2653         }
2654         if !host_supertraits.is_empty() {
2655             uwrite!(self.src, ": {}", host_supertraits.join(" + "));
2656         }
2657         uwriteln!(self.src, " {{");
2658 
2659         let has_concurrent_function = iface.functions.iter().any(|(_, func)| {
2660             matches!(func.kind, FunctionKind::Freestanding)
2661                 && matches!(
2662                     self.generator
2663                         .opts
2664                         .import_call_style(self.qualifier().as_deref(), &func.name),
2665                     CallStyle::Concurrent
2666                 )
2667         });
2668 
2669         if has_concurrent_function {
2670             self.push_str("type Data;\n");
2671         }
2672 
2673         for (_, func) in iface.functions.iter() {
2674             match func.kind {
2675                 FunctionKind::Freestanding => {}
2676                 _ => continue,
2677             }
2678             self.generate_function_trait_sig(func, "Data");
2679             self.push_str(";\n");
2680         }
2681 
2682         // Generate `convert_*` functions to convert custom trappable errors
2683         // into the representation required by Wasmtime's component API.
2684         let mut required_conversion_traits = IndexSet::new();
2685         let mut errors_converted = IndexMap::new();
2686         let mut my_error_types = iface
2687             .types
2688             .iter()
2689             .filter(|(_, id)| self.generator.trappable_errors.contains_key(*id))
2690             .map(|(_, id)| *id)
2691             .collect::<Vec<_>>();
2692         my_error_types.extend(
2693             iface
2694                 .functions
2695                 .iter()
2696                 .filter_map(|(_, func)| self.special_case_trappable_error(func))
2697                 .map(|(_, id, _)| id),
2698         );
2699         let root = self.path_to_root();
2700         for err_id in my_error_types {
2701             let custom_name = &self.generator.trappable_errors[&err_id];
2702             let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err_id)];
2703             let err_name = err.name.as_ref().unwrap();
2704             let err_snake = err_name.to_snake_case();
2705             let err_camel = err_name.to_upper_camel_case();
2706             let owner = match err.owner {
2707                 TypeOwner::Interface(i) => i,
2708                 _ => unimplemented!(),
2709             };
2710             match self.path_to_interface(owner) {
2711                 Some(path) => {
2712                     required_conversion_traits.insert(format!("{path}::Host"));
2713                 }
2714                 None => {
2715                     if errors_converted.insert(err_name, err_id).is_none() {
2716                         uwriteln!(
2717                             self.src,
2718                             "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> {wt}::Result<{err_camel}>;"
2719                         );
2720                     }
2721                 }
2722             }
2723         }
2724         uwriteln!(self.src, "}}");
2725 
2726         let (data_bounds, mut host_bounds, mut get_host_bounds) =
2727             match self.generator.opts.call_style() {
2728                 CallStyle::Async => (
2729                     "T: Send,".to_string(),
2730                     "Host + Send".to_string(),
2731                     "Host + Send".to_string(),
2732                 ),
2733                 CallStyle::Concurrent => {
2734                     let constraints = concurrent_constraints(
2735                         self.resolve,
2736                         &self.generator.opts,
2737                         self.qualifier().as_deref(),
2738                         id,
2739                     );
2740 
2741                     (
2742                         "T: Send + 'static,".to_string(),
2743                         format!("Host{} + Send", constraints("T")),
2744                         format!("Host{} + Send", constraints("D")),
2745                     )
2746                 }
2747                 CallStyle::Sync => (String::new(), "Host".to_string(), "Host".to_string()),
2748             };
2749 
2750         for ty in required_conversion_traits {
2751             uwrite!(host_bounds, " + {ty}");
2752             uwrite!(get_host_bounds, " + {ty}");
2753         }
2754 
2755         let (options_param, options_arg) = if self.generator.interface_link_options[&id].has_any() {
2756             ("options: &LinkOptions,", ", options")
2757         } else {
2758             ("", "")
2759         };
2760 
2761         uwriteln!(
2762             self.src,
2763             "
2764                 pub trait GetHost<T, D>:
2765                     Fn(T) -> <Self as GetHost<T, D>>::Host
2766                         + Send
2767                         + Sync
2768                         + Copy
2769                         + 'static
2770                 {{
2771                     type Host: {get_host_bounds};
2772                 }}
2773 
2774                 impl<F, T, D, O> GetHost<T, D> for F
2775                 where
2776                     F: Fn(T) -> O + Send + Sync + Copy + 'static,
2777                     O: {get_host_bounds},
2778                 {{
2779                     type Host = O;
2780                 }}
2781 
2782                 pub fn add_to_linker_get_host<T, G: for<'a> GetHost<&'a mut T, T, Host: {host_bounds}>>(
2783                     linker: &mut {wt}::component::Linker<T>,
2784                     {options_param}
2785                     host_getter: G,
2786                 ) -> {wt}::Result<()>
2787                     where {data_bounds}
2788                 {{
2789             "
2790         );
2791         let gate = FeatureGate::open(&mut self.src, &iface.stability);
2792         uwriteln!(self.src, "let mut inst = linker.instance(\"{name}\")?;");
2793 
2794         for (ty, name) in get_resources(self.resolve, id) {
2795             Wasmtime::generate_add_resource_to_linker(
2796                 self.qualifier().as_deref(),
2797                 &mut self.src,
2798                 &self.generator.opts,
2799                 &wt,
2800                 "inst",
2801                 name,
2802                 &self.resolve.types[ty].stability,
2803             );
2804         }
2805 
2806         for (_, func) in iface.functions.iter() {
2807             self.generate_add_function_to_linker(owner, func, "inst");
2808         }
2809         gate.close(&mut self.src);
2810         uwriteln!(self.src, "Ok(())");
2811         uwriteln!(self.src, "}}");
2812 
2813         if !self.generator.opts.skip_mut_forwarding_impls {
2814             // Generate add_to_linker (with closure)
2815             uwriteln!(
2816                 self.src,
2817                 "
2818                 pub fn add_to_linker<T, U>(
2819                     linker: &mut {wt}::component::Linker<T>,
2820                     {options_param}
2821                     get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
2822                 ) -> {wt}::Result<()>
2823                     where
2824                         U: {host_bounds}, {data_bounds}
2825                 {{
2826                     add_to_linker_get_host(linker {options_arg}, get)
2827                 }}
2828                 "
2829             );
2830 
2831             // Generate impl Host for &mut Host
2832             let maybe_send = if is_maybe_async { "+ Send" } else { "" };
2833 
2834             let maybe_maybe_sized = if has_concurrent_function {
2835                 ""
2836             } else {
2837                 "+ ?Sized"
2838             };
2839 
2840             uwriteln!(
2841                 self.src,
2842                 "impl<_T: Host {maybe_maybe_sized} {maybe_send}> Host for &mut _T {{"
2843             );
2844 
2845             if has_concurrent_function {
2846                 self.push_str("type Data = _T::Data;\n");
2847             }
2848 
2849             // Forward each method call to &mut T
2850             for (_, func) in iface.functions.iter() {
2851                 match func.kind {
2852                     FunctionKind::Freestanding => {}
2853                     _ => continue,
2854                 }
2855                 let call_style = self
2856                     .generator
2857                     .opts
2858                     .import_call_style(self.qualifier().as_deref(), &func.name);
2859                 self.generate_function_trait_sig(func, "Data");
2860                 if let CallStyle::Concurrent = call_style {
2861                     uwrite!(
2862                         self.src,
2863                         "{{ <_T as Host>::{}(store,",
2864                         rust_function_name(func)
2865                     );
2866                 } else {
2867                     uwrite!(self.src, "{{ Host::{}(*self,", rust_function_name(func));
2868                 }
2869                 for (name, _) in func.params.iter() {
2870                     uwrite!(self.src, "{},", to_rust_ident(name));
2871                 }
2872                 uwrite!(self.src, ")");
2873                 if let CallStyle::Async = call_style {
2874                     uwrite!(self.src, ".await");
2875                 }
2876                 uwriteln!(self.src, "}}");
2877             }
2878             for (err_name, err_id) in errors_converted {
2879                 uwriteln!(
2880                     self.src,
2881                     "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> {wt}::Result<{err_camel}> {{
2882                         Host::convert_{err_snake}(*self, err)
2883                     }}",
2884                     custom_name = self.generator.trappable_errors[&err_id],
2885                     err_snake = err_name.to_snake_case(),
2886                     err_camel = err_name.to_upper_camel_case(),
2887                 );
2888             }
2889             uwriteln!(self.src, "}}");
2890         }
2891     }
2892 
2893     fn qualifier(&self) -> Option<String> {
2894         self.current_interface
2895             .map(|(_, key, _)| self.resolve.name_world_key(key))
2896     }
2897 
2898     fn generate_add_function_to_linker(&mut self, owner: TypeOwner, func: &Function, linker: &str) {
2899         let gate = FeatureGate::open(&mut self.src, &func.stability);
2900         uwrite!(
2901             self.src,
2902             "{linker}.{}(\"{}\", ",
2903             match self
2904                 .generator
2905                 .opts
2906                 .import_call_style(self.qualifier().as_deref(), &func.name)
2907             {
2908                 CallStyle::Sync => "func_wrap",
2909                 CallStyle::Async => "func_wrap_async",
2910                 CallStyle::Concurrent => "func_wrap_concurrent",
2911             },
2912             func.name
2913         );
2914         self.generate_guest_import_closure(owner, func);
2915         uwriteln!(self.src, ")?;");
2916         gate.close(&mut self.src);
2917     }
2918 
2919     fn generate_guest_import_closure(&mut self, owner: TypeOwner, func: &Function) {
2920         // Generate the closure that's passed to a `Linker`, the final piece of
2921         // codegen here.
2922 
2923         let wt = self.generator.wasmtime_path();
2924         uwrite!(
2925             self.src,
2926             "move |mut caller: {wt}::StoreContextMut<'_, T>, ("
2927         );
2928         for (i, _param) in func.params.iter().enumerate() {
2929             uwrite!(self.src, "arg{},", i);
2930         }
2931         self.src.push_str(") : (");
2932 
2933         for (_, ty) in func.params.iter() {
2934             // Lift is required to be implied for this type, so we can't use
2935             // a borrowed type:
2936             self.print_ty(ty, TypeMode::Owned);
2937             self.src.push_str(", ");
2938         }
2939         self.src.push_str(")| {\n");
2940 
2941         let style = self
2942             .generator
2943             .opts
2944             .import_call_style(self.qualifier().as_deref(), &func.name);
2945 
2946         if self.generator.opts.tracing {
2947             if let CallStyle::Async = style {
2948                 self.src.push_str("use tracing::Instrument;\n");
2949             }
2950 
2951             uwrite!(
2952                 self.src,
2953                 "
2954                    let span = tracing::span!(
2955                        tracing::Level::TRACE,
2956                        \"wit-bindgen import\",
2957                        module = \"{}\",
2958                        function = \"{}\",
2959                    );
2960                ",
2961                 match owner {
2962                     TypeOwner::Interface(id) => self.resolve.interfaces[id]
2963                         .name
2964                         .as_deref()
2965                         .unwrap_or("<no module>"),
2966                     TypeOwner::World(id) => &self.resolve.worlds[id].name,
2967                     TypeOwner::None => "<no owner>",
2968                 },
2969                 func.name,
2970             );
2971         }
2972 
2973         if let CallStyle::Async = &style {
2974             uwriteln!(
2975                 self.src,
2976                 " {wt}::component::__internal::Box::new(async move {{ "
2977             );
2978         } else {
2979             // Only directly enter the span if the function is sync. Otherwise
2980             // we use tracing::Instrument to ensure that the span is not entered
2981             // across an await point.
2982             if self.generator.opts.tracing {
2983                 self.push_str("let _enter = span.enter();\n");
2984             }
2985         }
2986 
2987         if self.generator.opts.tracing {
2988             let mut event_fields = func
2989                 .params
2990                 .iter()
2991                 .enumerate()
2992                 .map(|(i, (name, ty))| {
2993                     let name = to_rust_ident(&name);
2994                     formatting_for_arg(&name, i, *ty, &self.generator.opts, &self.resolve)
2995                 })
2996                 .collect::<Vec<String>>();
2997             event_fields.push(format!("\"call\""));
2998             uwrite!(
2999                 self.src,
3000                 "tracing::event!(tracing::Level::TRACE, {});\n",
3001                 event_fields.join(", ")
3002             );
3003         }
3004 
3005         self.src.push_str(if let CallStyle::Concurrent = &style {
3006             "let host = caller;\n"
3007         } else {
3008             "let host = &mut host_getter(caller.data_mut());\n"
3009         });
3010         let func_name = rust_function_name(func);
3011         let host_trait = match func.kind {
3012             FunctionKind::Freestanding => match owner {
3013                 TypeOwner::World(id) => format!(
3014                     "{}Imports",
3015                     rust::to_rust_upper_camel_case(&self.resolve.worlds[id].name)
3016                 ),
3017                 _ => "Host".to_string(),
3018             },
3019             FunctionKind::Method(id) | FunctionKind::Static(id) | FunctionKind::Constructor(id) => {
3020                 let resource = self.resolve.types[id]
3021                     .name
3022                     .as_ref()
3023                     .unwrap()
3024                     .to_upper_camel_case();
3025                 format!("Host{resource}")
3026             }
3027         };
3028 
3029         if let CallStyle::Concurrent = &style {
3030             uwrite!(
3031                 self.src,
3032                 "let r = <G::Host as {host_trait}>::{func_name}(host, "
3033             );
3034         } else {
3035             uwrite!(self.src, "let r = {host_trait}::{func_name}(host, ");
3036         }
3037 
3038         for (i, _) in func.params.iter().enumerate() {
3039             uwrite!(self.src, "arg{},", i);
3040         }
3041 
3042         self.src.push_str(match &style {
3043             CallStyle::Sync | CallStyle::Concurrent => ");\n",
3044             CallStyle::Async => ").await;\n",
3045         });
3046 
3047         if let CallStyle::Concurrent = &style {
3048             self.src.push_str(
3049                 "Box::pin(async move {
3050                      let fun = r.await;
3051                      Box::new(move |mut caller: wasmtime::StoreContextMut<'_, T>| {
3052                          let r = fun(caller);
3053                 ",
3054             );
3055         }
3056 
3057         if self.generator.opts.tracing {
3058             uwrite!(
3059                 self.src,
3060                 "tracing::event!(tracing::Level::TRACE, {}, \"return\");",
3061                 formatting_for_results(func.result, &self.generator.opts, &self.resolve)
3062             );
3063         }
3064 
3065         if !self.generator.opts.trappable_imports.can_trap(&func) {
3066             if func.result.is_some() {
3067                 uwrite!(self.src, "Ok((r,))\n");
3068             } else {
3069                 uwrite!(self.src, "Ok(r)\n");
3070             }
3071         } else if let Some((_, err, _)) = self.special_case_trappable_error(func) {
3072             let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err)];
3073             let err_name = err.name.as_ref().unwrap();
3074             let owner = match err.owner {
3075                 TypeOwner::Interface(i) => i,
3076                 _ => unimplemented!(),
3077             };
3078             let convert_trait = match self.path_to_interface(owner) {
3079                 Some(path) => format!("{path}::Host"),
3080                 None => format!("Host"),
3081             };
3082             let convert = format!("{}::convert_{}", convert_trait, err_name.to_snake_case());
3083             uwrite!(
3084                 self.src,
3085                 "Ok((match r {{
3086                     Ok(a) => Ok(a),
3087                     Err(e) => Err({convert}(host, e)?),
3088                 }},))"
3089             );
3090         } else if func.result.is_some() {
3091             uwrite!(self.src, "Ok((r?,))\n");
3092         } else {
3093             uwrite!(self.src, "r\n");
3094         }
3095 
3096         match &style {
3097             CallStyle::Sync => (),
3098             CallStyle::Async => {
3099                 if self.generator.opts.tracing {
3100                     self.src.push_str("}.instrument(span))\n");
3101                 } else {
3102                     self.src.push_str("})\n");
3103                 }
3104             }
3105             CallStyle::Concurrent => {
3106                 let old_source = mem::take(&mut self.src);
3107                 self.print_result_ty_tuple(func.result, TypeMode::Owned);
3108                 let result_type = String::from(mem::replace(&mut self.src, old_source));
3109                 let box_fn = format!(
3110                     "Box<dyn FnOnce(wasmtime::StoreContextMut<'_, T>) -> \
3111                      wasmtime::Result<{result_type}> + Send + Sync>"
3112                 );
3113                 uwriteln!(
3114                     self.src,
3115                     "        }}) as {box_fn}
3116                          }}) as ::core::pin::Pin<Box<dyn ::core::future::Future<Output = {box_fn}> \
3117                                + Send + Sync + 'static>>
3118                     "
3119                 );
3120             }
3121         }
3122         self.src.push_str("}\n");
3123     }
3124 
3125     fn generate_function_trait_sig(&mut self, func: &Function, data: &str) {
3126         let wt = self.generator.wasmtime_path();
3127         self.rustdoc(&func.docs);
3128 
3129         let style = self
3130             .generator
3131             .opts
3132             .import_call_style(self.qualifier().as_deref(), &func.name);
3133         if let CallStyle::Async = &style {
3134             self.push_str("async ");
3135         }
3136         self.push_str("fn ");
3137         self.push_str(&rust_function_name(func));
3138         self.push_str(&if let CallStyle::Concurrent = &style {
3139             format!("(store: wasmtime::StoreContextMut<'_, Self::{data}>, ")
3140         } else {
3141             "(&mut self, ".to_string()
3142         });
3143         for (name, param) in func.params.iter() {
3144             let name = to_rust_ident(name);
3145             self.push_str(&name);
3146             self.push_str(": ");
3147             self.print_ty(param, TypeMode::Owned);
3148             self.push_str(",");
3149         }
3150         self.push_str(")");
3151         self.push_str(" -> ");
3152 
3153         if let CallStyle::Concurrent = &style {
3154             uwrite!(self.src, "impl ::core::future::Future<Output = impl FnOnce(wasmtime::StoreContextMut<'_, Self::{data}>) -> ");
3155         }
3156 
3157         if !self.generator.opts.trappable_imports.can_trap(func) {
3158             self.print_result_ty(func.result, TypeMode::Owned);
3159         } else if let Some((r, _id, error_typename)) = self.special_case_trappable_error(func) {
3160             // Functions which have a single result `result<ok,err>` get special
3161             // cased to use the host_wasmtime_rust::Error<err>, making it possible
3162             // for them to trap or use `?` to propagate their errors
3163             self.push_str("Result<");
3164             if let Some(ok) = r.ok {
3165                 self.print_ty(&ok, TypeMode::Owned);
3166             } else {
3167                 self.push_str("()");
3168             }
3169             self.push_str(",");
3170             self.push_str(&error_typename);
3171             self.push_str(">");
3172         } else {
3173             // All other functions get their return values wrapped in an wasmtime::Result.
3174             // Returning the anyhow::Error case can be used to trap.
3175             uwrite!(self.src, "{wt}::Result<");
3176             self.print_result_ty(func.result, TypeMode::Owned);
3177             self.push_str(">");
3178         }
3179 
3180         if let CallStyle::Concurrent = &style {
3181             self.push_str(" + Send + Sync + 'static> + Send + Sync + 'static where Self: Sized");
3182         }
3183     }
3184 
3185     fn extract_typed_function(&mut self, func: &Function) -> (String, String) {
3186         let prev = mem::take(&mut self.src);
3187         let snake = func_field_name(self.resolve, func);
3188         uwrite!(self.src, "*_instance.get_typed_func::<(");
3189         for (_, ty) in func.params.iter() {
3190             self.print_ty(ty, TypeMode::AllBorrowed("'_"));
3191             self.push_str(", ");
3192         }
3193         self.src.push_str("), (");
3194         if let Some(ty) = func.result {
3195             self.print_ty(&ty, TypeMode::Owned);
3196             self.push_str(", ");
3197         }
3198         uwriteln!(self.src, ")>(&mut store, &self.{snake})?.func()");
3199 
3200         let ret = (snake, mem::take(&mut self.src).to_string());
3201         self.src = prev;
3202         ret
3203     }
3204 
3205     fn define_rust_guest_export(
3206         &mut self,
3207         resolve: &Resolve,
3208         ns: Option<&WorldKey>,
3209         func: &Function,
3210     ) {
3211         // Exports must be async if anything could be async, it's just imports
3212         // that get to be optionally async/sync.
3213         let style = self.generator.opts.call_style();
3214         let (async_, async__, await_, concurrent) = match &style {
3215             CallStyle::Async | CallStyle::Concurrent => {
3216                 if self.generator.opts.concurrent_exports {
3217                     ("async", "INVALID", "INVALID", true)
3218                 } else {
3219                     ("async", "_async", ".await", false)
3220                 }
3221             }
3222             CallStyle::Sync => ("", "", "", false),
3223         };
3224 
3225         self.rustdoc(&func.docs);
3226         let wt = self.generator.wasmtime_path();
3227 
3228         uwrite!(
3229             self.src,
3230             "pub {async_} fn call_{}<S: {wt}::AsContextMut>(&self, mut store: S, ",
3231             func.item_name().to_snake_case(),
3232         );
3233 
3234         let param_mode = if let CallStyle::Concurrent = &style {
3235             TypeMode::Owned
3236         } else {
3237             TypeMode::AllBorrowed("'_")
3238         };
3239 
3240         for (i, param) in func.params.iter().enumerate() {
3241             uwrite!(self.src, "arg{}: ", i);
3242             self.print_ty(&param.1, param_mode);
3243             self.push_str(",");
3244         }
3245 
3246         uwrite!(self.src, ") -> {wt}::Result<");
3247         if concurrent {
3248             uwrite!(self.src, "{wt}::component::Promise<");
3249         }
3250         self.print_result_ty(func.result, TypeMode::Owned);
3251         if concurrent {
3252             uwrite!(self.src, ">");
3253         }
3254 
3255         let maybe_static = if concurrent { " + 'static" } else { "" };
3256 
3257         uwrite!(
3258             self.src,
3259             "> where <S as {wt}::AsContext>::Data: Send{maybe_static} {{\n"
3260         );
3261 
3262         // TODO: support tracing concurrent calls
3263         if self.generator.opts.tracing && !concurrent {
3264             if let CallStyle::Async = &style {
3265                 self.src.push_str("use tracing::Instrument;\n");
3266             }
3267 
3268             let ns = match ns {
3269                 Some(key) => resolve.name_world_key(key),
3270                 None => "default".to_string(),
3271             };
3272             self.src.push_str(&format!(
3273                 "
3274                    let span = tracing::span!(
3275                        tracing::Level::TRACE,
3276                        \"wit-bindgen export\",
3277                        module = \"{ns}\",
3278                        function = \"{}\",
3279                    );
3280                ",
3281                 func.name,
3282             ));
3283 
3284             if !matches!(&style, CallStyle::Async) {
3285                 self.src.push_str(
3286                     "
3287                    let _enter = span.enter();
3288                    ",
3289                 );
3290             }
3291         }
3292 
3293         self.src.push_str("let callee = unsafe {\n");
3294         uwrite!(self.src, "{wt}::component::TypedFunc::<(");
3295         for (_, ty) in func.params.iter() {
3296             self.print_ty(ty, param_mode);
3297             self.push_str(", ");
3298         }
3299         self.src.push_str("), (");
3300         if let Some(ty) = func.result {
3301             self.print_ty(&ty, TypeMode::Owned);
3302             self.push_str(", ");
3303         }
3304         let projection_to_func = match &func.kind {
3305             FunctionKind::Freestanding => "",
3306             _ => ".funcs",
3307         };
3308         uwriteln!(
3309             self.src,
3310             ")>::new_unchecked(self{projection_to_func}.{})",
3311             func_field_name(self.resolve, func),
3312         );
3313         self.src.push_str("};\n");
3314 
3315         if concurrent {
3316             uwrite!(
3317                 self.src,
3318                 "let promise = callee.call_concurrent(store.as_context_mut(), ("
3319             );
3320             for (i, _) in func.params.iter().enumerate() {
3321                 uwrite!(self.src, "arg{i}, ");
3322             }
3323             self.src.push_str(")).await?;");
3324 
3325             if func.result.is_some() {
3326                 self.src.push_str("Ok(promise.map(|(v,)| v))\n");
3327             } else {
3328                 self.src.push_str("Ok(promise)");
3329             }
3330         } else {
3331             self.src.push_str("let (");
3332             if func.result.is_some() {
3333                 uwrite!(self.src, "ret0,");
3334             }
3335             uwrite!(
3336                 self.src,
3337                 ") = callee.call{async__}(store.as_context_mut(), ("
3338             );
3339             for (i, _) in func.params.iter().enumerate() {
3340                 uwrite!(self.src, "arg{}, ", i);
3341             }
3342 
3343             let instrument = if matches!(&style, CallStyle::Async) && self.generator.opts.tracing {
3344                 ".instrument(span.clone())"
3345             } else {
3346                 ""
3347             };
3348             uwriteln!(self.src, ")){instrument}{await_}?;");
3349 
3350             let instrument = if matches!(&style, CallStyle::Async) && self.generator.opts.tracing {
3351                 ".instrument(span)"
3352             } else {
3353                 ""
3354             };
3355 
3356             uwriteln!(
3357                 self.src,
3358                 "callee.post_return{async__}(store.as_context_mut()){instrument}{await_}?;"
3359             );
3360 
3361             self.src.push_str("Ok(");
3362             if func.result.is_some() {
3363                 self.src.push_str("ret0");
3364             } else {
3365                 self.src.push_str("()");
3366             }
3367             self.src.push_str(")\n");
3368         }
3369 
3370         // End function body
3371         self.src.push_str("}\n");
3372     }
3373 
3374     fn rustdoc(&mut self, docs: &Docs) {
3375         let docs = match &docs.contents {
3376             Some(docs) => docs,
3377             None => return,
3378         };
3379         for line in docs.trim().lines() {
3380             self.push_str("/// ");
3381             self.push_str(line);
3382             self.push_str("\n");
3383         }
3384     }
3385 
3386     fn path_to_root(&self) -> String {
3387         let mut path_to_root = String::new();
3388         if let Some((_, key, is_export)) = self.current_interface {
3389             match key {
3390                 WorldKey::Name(_) => {
3391                     path_to_root.push_str("super::");
3392                 }
3393                 WorldKey::Interface(_) => {
3394                     path_to_root.push_str("super::super::super::");
3395                 }
3396             }
3397             if is_export {
3398                 path_to_root.push_str("super::");
3399             }
3400         }
3401         path_to_root
3402     }
3403 }
3404 
3405 impl<'a> RustGenerator<'a> for InterfaceGenerator<'a> {
3406     fn resolve(&self) -> &'a Resolve {
3407         self.resolve
3408     }
3409 
3410     fn ownership(&self) -> Ownership {
3411         self.generator.opts.ownership
3412     }
3413 
3414     fn path_to_interface(&self, interface: InterfaceId) -> Option<String> {
3415         if let Some((cur, _, _)) = self.current_interface {
3416             if cur == interface {
3417                 return None;
3418             }
3419         }
3420         let mut path_to_root = self.path_to_root();
3421         match &self.generator.interface_names[&interface] {
3422             InterfaceName::Remapped { name_at_root, .. } => path_to_root.push_str(name_at_root),
3423             InterfaceName::Path(path) => {
3424                 for (i, name) in path.iter().enumerate() {
3425                     if i > 0 {
3426                         path_to_root.push_str("::");
3427                     }
3428                     path_to_root.push_str(name);
3429                 }
3430             }
3431         }
3432         Some(path_to_root)
3433     }
3434 
3435     fn push_str(&mut self, s: &str) {
3436         self.src.push_str(s);
3437     }
3438 
3439     fn info(&self, ty: TypeId) -> TypeInfo {
3440         self.generator.types.get(ty)
3441     }
3442 
3443     fn is_imported_interface(&self, interface: InterfaceId) -> bool {
3444         self.generator.interface_last_seen_as_import[&interface]
3445     }
3446 
3447     fn wasmtime_path(&self) -> String {
3448         self.generator.wasmtime_path()
3449     }
3450 }
3451 
3452 #[derive(Default)]
3453 struct LinkOptionsBuilder {
3454     unstable_features: BTreeSet<String>,
3455 }
3456 impl LinkOptionsBuilder {
3457     fn has_any(&self) -> bool {
3458         !self.unstable_features.is_empty()
3459     }
3460     fn add_world(&mut self, resolve: &Resolve, id: &WorldId) {
3461         let world = &resolve.worlds[*id];
3462 
3463         self.add_stability(&world.stability);
3464 
3465         for (_, import) in world.imports.iter() {
3466             match import {
3467                 WorldItem::Interface { id, stability } => {
3468                     self.add_stability(stability);
3469                     self.add_interface(resolve, id);
3470                 }
3471                 WorldItem::Function(f) => {
3472                     self.add_stability(&f.stability);
3473                 }
3474                 WorldItem::Type(t) => {
3475                     self.add_type(resolve, t);
3476                 }
3477             }
3478         }
3479     }
3480     fn add_interface(&mut self, resolve: &Resolve, id: &InterfaceId) {
3481         let interface = &resolve.interfaces[*id];
3482 
3483         self.add_stability(&interface.stability);
3484 
3485         for (_, t) in interface.types.iter() {
3486             self.add_type(resolve, t);
3487         }
3488         for (_, f) in interface.functions.iter() {
3489             self.add_stability(&f.stability);
3490         }
3491     }
3492     fn add_type(&mut self, resolve: &Resolve, id: &TypeId) {
3493         let t = &resolve.types[*id];
3494         self.add_stability(&t.stability);
3495     }
3496     fn add_stability(&mut self, stability: &Stability) {
3497         match stability {
3498             Stability::Unstable { feature, .. } => {
3499                 self.unstable_features.insert(feature.clone());
3500             }
3501             Stability::Stable { .. } | Stability::Unknown => {}
3502         }
3503     }
3504     fn write_struct(&self, src: &mut Source) {
3505         if !self.has_any() {
3506             return;
3507         }
3508 
3509         let mut unstable_features = self.unstable_features.iter().cloned().collect::<Vec<_>>();
3510         unstable_features.sort();
3511 
3512         uwriteln!(
3513             src,
3514             "
3515             /// Link-time configurations.
3516             #[derive(Clone, Debug, Default)]
3517             pub struct LinkOptions {{
3518             "
3519         );
3520 
3521         for feature in unstable_features.iter() {
3522             let feature_rust_name = feature.to_snake_case();
3523             uwriteln!(src, "{feature_rust_name}: bool,");
3524         }
3525 
3526         uwriteln!(src, "}}");
3527         uwriteln!(src, "impl LinkOptions {{");
3528 
3529         for feature in unstable_features.iter() {
3530             let feature_rust_name = feature.to_snake_case();
3531             uwriteln!(
3532                 src,
3533                 "
3534                 /// Enable members marked as `@unstable(feature = {feature})`
3535                 pub fn {feature_rust_name}(&mut self, enabled: bool) -> &mut Self {{
3536                     self.{feature_rust_name} = enabled;
3537                     self
3538                 }}
3539             "
3540             );
3541         }
3542 
3543         uwriteln!(src, "}}");
3544     }
3545     fn write_impl_from_world(&self, src: &mut Source, path: &str) {
3546         if !self.has_any() {
3547             return;
3548         }
3549 
3550         let mut unstable_features = self.unstable_features.iter().cloned().collect::<Vec<_>>();
3551         unstable_features.sort();
3552 
3553         uwriteln!(
3554             src,
3555             "
3556             impl core::convert::From<LinkOptions> for {path}::LinkOptions {{
3557                 fn from(src: LinkOptions) -> Self {{
3558                     (&src).into()
3559                 }}
3560             }}
3561 
3562             impl core::convert::From<&LinkOptions> for {path}::LinkOptions {{
3563                 fn from(src: &LinkOptions) -> Self {{
3564                     let mut dest = Self::default();
3565         "
3566         );
3567 
3568         for feature in unstable_features.iter() {
3569             let feature_rust_name = feature.to_snake_case();
3570             uwriteln!(src, "dest.{feature_rust_name}(src.{feature_rust_name});");
3571         }
3572 
3573         uwriteln!(
3574             src,
3575             "
3576                     dest
3577                 }}
3578             }}
3579         "
3580         );
3581     }
3582 }
3583 
3584 struct FeatureGate {
3585     close: bool,
3586 }
3587 impl FeatureGate {
3588     fn open(src: &mut Source, stability: &Stability) -> FeatureGate {
3589         let close = if let Stability::Unstable { feature, .. } = stability {
3590             let feature_rust_name = feature.to_snake_case();
3591             uwrite!(src, "if options.{feature_rust_name} {{");
3592             true
3593         } else {
3594             false
3595         };
3596         Self { close }
3597     }
3598 
3599     fn close(self, src: &mut Source) {
3600         if self.close {
3601             uwriteln!(src, "}}");
3602         }
3603     }
3604 }
3605 
3606 /// Produce a string for tracing a function argument.
3607 fn formatting_for_arg(
3608     name: &str,
3609     index: usize,
3610     ty: Type,
3611     opts: &Opts,
3612     resolve: &Resolve,
3613 ) -> String {
3614     if !opts.verbose_tracing && type_contains_lists(ty, resolve) {
3615         return format!("{name} = tracing::field::debug(\"...\")");
3616     }
3617 
3618     // Normal tracing.
3619     format!("{name} = tracing::field::debug(&arg{index})")
3620 }
3621 
3622 /// Produce a string for tracing function results.
3623 fn formatting_for_results(result: Option<Type>, opts: &Opts, resolve: &Resolve) -> String {
3624     let contains_lists = match result {
3625         Some(ty) => type_contains_lists(ty, resolve),
3626         None => false,
3627     };
3628 
3629     if !opts.verbose_tracing && contains_lists {
3630         return format!("result = tracing::field::debug(\"...\")");
3631     }
3632 
3633     // Normal tracing.
3634     format!("result = tracing::field::debug(&r)")
3635 }
3636 
3637 /// Test whether the given type contains lists.
3638 ///
3639 /// Here, a `string` is not considered a list.
3640 fn type_contains_lists(ty: Type, resolve: &Resolve) -> bool {
3641     match ty {
3642         Type::Id(id) => match &resolve.types[id].kind {
3643             TypeDefKind::Resource
3644             | TypeDefKind::Unknown
3645             | TypeDefKind::Flags(_)
3646             | TypeDefKind::Handle(_)
3647             | TypeDefKind::Enum(_)
3648             | TypeDefKind::Stream(_)
3649             | TypeDefKind::Future(_)
3650             | TypeDefKind::ErrorContext => false,
3651             TypeDefKind::Option(ty) => type_contains_lists(*ty, resolve),
3652             TypeDefKind::Result(Result_ { ok, err }) => {
3653                 option_type_contains_lists(*ok, resolve)
3654                     || option_type_contains_lists(*err, resolve)
3655             }
3656             TypeDefKind::Record(record) => record
3657                 .fields
3658                 .iter()
3659                 .any(|field| type_contains_lists(field.ty, resolve)),
3660             TypeDefKind::Tuple(tuple) => tuple
3661                 .types
3662                 .iter()
3663                 .any(|ty| type_contains_lists(*ty, resolve)),
3664             TypeDefKind::Variant(variant) => variant
3665                 .cases
3666                 .iter()
3667                 .any(|case| option_type_contains_lists(case.ty, resolve)),
3668             TypeDefKind::Type(ty) => type_contains_lists(*ty, resolve),
3669             TypeDefKind::List(_) => true,
3670         },
3671 
3672         // Technically strings are lists too, but we ignore that here because
3673         // they're usually short.
3674         _ => false,
3675     }
3676 }
3677 
3678 fn option_type_contains_lists(ty: Option<Type>, resolve: &Resolve) -> bool {
3679     match ty {
3680         Some(ty) => type_contains_lists(ty, resolve),
3681         None => false,
3682     }
3683 }
3684 
3685 /// When an interface `use`s a type from another interface, it creates a new TypeId
3686 /// referring to the definition TypeId. Chase this chain of references down to
3687 /// a TypeId for type's definition.
3688 fn resolve_type_definition_id(resolve: &Resolve, mut id: TypeId) -> TypeId {
3689     loop {
3690         match resolve.types[id].kind {
3691             TypeDefKind::Type(Type::Id(def_id)) => id = def_id,
3692             _ => return id,
3693         }
3694     }
3695 }
3696 
3697 fn rust_function_name(func: &Function) -> String {
3698     match func.kind {
3699         FunctionKind::Method(_) | FunctionKind::Static(_) => to_rust_ident(func.item_name()),
3700         FunctionKind::Constructor(_) => "new".to_string(),
3701         FunctionKind::Freestanding => to_rust_ident(&func.name),
3702     }
3703 }
3704 
3705 fn func_field_name(resolve: &Resolve, func: &Function) -> String {
3706     let mut name = String::new();
3707     match func.kind {
3708         FunctionKind::Method(id) => {
3709             name.push_str("method-");
3710             name.push_str(resolve.types[id].name.as_ref().unwrap());
3711             name.push_str("-");
3712         }
3713         FunctionKind::Static(id) => {
3714             name.push_str("static-");
3715             name.push_str(resolve.types[id].name.as_ref().unwrap());
3716             name.push_str("-");
3717         }
3718         FunctionKind::Constructor(id) => {
3719             name.push_str("constructor-");
3720             name.push_str(resolve.types[id].name.as_ref().unwrap());
3721             name.push_str("-");
3722         }
3723         FunctionKind::Freestanding => {}
3724     }
3725     name.push_str(func.item_name());
3726     name.to_snake_case()
3727 }
3728 
3729 fn get_resources<'a>(
3730     resolve: &'a Resolve,
3731     id: InterfaceId,
3732 ) -> impl Iterator<Item = (TypeId, &'a str)> + 'a {
3733     resolve.interfaces[id]
3734         .types
3735         .iter()
3736         .filter_map(move |(name, ty)| match &resolve.types[*ty].kind {
3737             TypeDefKind::Resource => Some((*ty, name.as_str())),
3738             _ => None,
3739         })
3740 }
3741 
3742 fn get_world_resources<'a>(
3743     resolve: &'a Resolve,
3744     id: WorldId,
3745 ) -> impl Iterator<Item = (TypeId, &'a str)> + 'a {
3746     resolve.worlds[id]
3747         .imports
3748         .iter()
3749         .filter_map(move |(name, item)| match item {
3750             WorldItem::Type(id) => match resolve.types[*id].kind {
3751                 TypeDefKind::Resource => Some(match name {
3752                     WorldKey::Name(s) => (*id, s.as_str()),
3753                     WorldKey::Interface(_) => unreachable!(),
3754                 }),
3755                 _ => None,
3756             },
3757             _ => None,
3758         })
3759 }
3760 
3761 fn concurrent_constraints<'a>(
3762     resolve: &'a Resolve,
3763     opts: &Opts,
3764     qualifier: Option<&str>,
3765     id: InterfaceId,
3766 ) -> impl Fn(&str) -> String + use<'a> {
3767     let has_concurrent_function = resolve.interfaces[id].functions.iter().any(|(_, func)| {
3768         matches!(func.kind, FunctionKind::Freestanding)
3769             && matches!(
3770                 opts.import_call_style(qualifier, &func.name),
3771                 CallStyle::Concurrent
3772             )
3773     });
3774 
3775     let types = resolve.interfaces[id]
3776         .types
3777         .iter()
3778         .filter_map(|(name, ty)| match resolve.types[*ty].kind {
3779             TypeDefKind::Resource
3780                 if resolve.interfaces[id]
3781                     .functions
3782                     .values()
3783                     .any(|func| match func.kind {
3784                         FunctionKind::Freestanding => false,
3785                         FunctionKind::Method(resource)
3786                         | FunctionKind::Static(resource)
3787                         | FunctionKind::Constructor(resource) => {
3788                             *ty == resource
3789                                 && matches!(
3790                                     opts.import_call_style(qualifier, &func.name),
3791                                     CallStyle::Concurrent
3792                                 )
3793                         }
3794                     }) =>
3795             {
3796                 Some(format!("{}Data", name.to_upper_camel_case()))
3797             }
3798             _ => None,
3799         })
3800         .chain(has_concurrent_function.then_some("Data".to_string()))
3801         .collect::<Vec<_>>();
3802 
3803     move |v| {
3804         if types.is_empty() {
3805             String::new()
3806         } else {
3807             format!(
3808                 "<{}>",
3809                 types
3810                     .iter()
3811                     .map(|s| format!("{s} = {v}"))
3812                     .collect::<Vec<_>>()
3813                     .join(", ")
3814             )
3815         }
3816     }
3817 }
3818 
3819 fn world_imports_concurrent_constraints<'a>(
3820     resolve: &'a Resolve,
3821     world: WorldId,
3822     opts: &Opts,
3823 ) -> impl Fn(&str) -> String + use<'a> {
3824     let has_concurrent_function = resolve.worlds[world]
3825         .imports
3826         .values()
3827         .any(|item| match item {
3828             WorldItem::Function(func) => {
3829                 matches!(func.kind, FunctionKind::Freestanding)
3830                     && matches!(
3831                         opts.import_call_style(None, &func.name),
3832                         CallStyle::Concurrent
3833                     )
3834             }
3835             WorldItem::Interface { .. } | WorldItem::Type(_) => false,
3836         });
3837 
3838     let types = resolve.worlds[world]
3839         .imports
3840         .iter()
3841         .filter_map(|(name, item)| match (name, item) {
3842             (WorldKey::Name(name), WorldItem::Type(ty)) => match resolve.types[*ty].kind {
3843                 TypeDefKind::Resource
3844                     if resolve.worlds[world]
3845                         .imports
3846                         .values()
3847                         .any(|item| match item {
3848                             WorldItem::Function(func) => match func.kind {
3849                                 FunctionKind::Freestanding => false,
3850                                 FunctionKind::Method(resource)
3851                                 | FunctionKind::Static(resource)
3852                                 | FunctionKind::Constructor(resource) => {
3853                                     *ty == resource
3854                                         && matches!(
3855                                             opts.import_call_style(None, &func.name),
3856                                             CallStyle::Concurrent
3857                                         )
3858                                 }
3859                             },
3860                             WorldItem::Interface { .. } | WorldItem::Type(_) => false,
3861                         }) =>
3862                 {
3863                     Some(format!("{}Data", name.to_upper_camel_case()))
3864                 }
3865                 _ => None,
3866             },
3867             _ => None,
3868         })
3869         .chain(has_concurrent_function.then_some("Data".to_string()))
3870         .collect::<Vec<_>>();
3871 
3872     move |v| {
3873         if types.is_empty() {
3874             String::new()
3875         } else {
3876             format!(
3877                 "<{}>",
3878                 types
3879                     .iter()
3880                     .map(|s| format!("{s} = {v}"))
3881                     .collect::<Vec<_>>()
3882                     .join(", ")
3883             )
3884         }
3885     }
3886 }
3887