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