Repository: bytecodealliance/wasm-tools
Pull request #2064 (2025-02-21 23:53:40)

More refactoring/reshuffling of component async intrinsics
As I continue to grapple with `wit-component`, `task.return`, and the addition of canonical options I've continued to find more locations which I'd like to refactor/improve related to how async intrinsics are handled. This is a series of a few minor refactorings leading up to a more major refactoring which changes the names of imported intrinsics. The end goal is to make all intrinsics "look more alike" to one another in terms of how they're detected/processed and avoid having two distinct paths for async and not-async. 

The final commit here is the meat of this PR which shuffles around where intrinsics are validated and how they're processed and additionally renames the imports that generate intrinsics. I've attempted to otherwise split this by commit in terms of logical units and additionally document each commit itself.


Patch:
diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs
index ae5bf046..628befe7 100644
--- a/crates/wit-component/src/encoding.rs
+++ b/crates/wit-component/src/encoding.rs
@@ -1042,7 +1042,7 @@ impl<'a> EncodingState<'a> {
             .unwrap();
         let exports = self.info.exports_for(module);
         let realloc_index = exports
-            .export_realloc_for(key, func)
+            .export_realloc_for(key, &func.name)
             .map(|name| self.core_alias_export(instance_index, name, ExportKind::Func));
         let mut options = options
             .into_iter(encoding, self.memory_index, realloc_index)?
@@ -1271,7 +1271,6 @@ impl<'a> EncodingState<'a> {
                     for_module,
                     info,
                     kind,
-                    async_: _,
                 } => {
                     let metadata = self.info.module_metadata_for(*for_module);
                     let exports = self.info.exports_for(*for_module);
@@ -1280,21 +1279,21 @@ impl<'a> EncodingState<'a> {
                         (
                             metadata
                                 .import_encodings
-                                .get(resolve, &info.key, &info.function.name),
-                            exports.import_realloc_for(info.interface, &info.function.name),
+                                .get(resolve, &info.key, &info.function),
+                            exports.import_realloc_for(info.interface, &info.function),
                         )
                     } else {
                         (
                             metadata
                                 .export_encodings
-                                .get(resolve, &info.key, &info.function.name),
+                                .get(resolve, &info.key, &info.function),
                             exports.export_realloc_for(&info.key, &info.function),
                         )
                     };
                     let encoding = encoding.unwrap_or(StringEncoding::UTF8);
                     let realloc_index = realloc
                         .map(|name| self.core_alias_export(instance_index, name, ExportKind::Func));
-                    let type_index = self.payload_type_index(info.ty, info.imported)?;
+                    let type_index = self.payload_type_index(info)?;
                     let options =
                         shim.options
                             .into_iter(encoding, self.memory_index, realloc_index)?;
@@ -1360,32 +1359,14 @@ impl<'a> EncodingState<'a> {
     /// Note that the payload type `T` of `stream<T>` or `future<T>` may be an
     /// imported or exported type, and that determines the appropriate type
     /// encoder to use.
-    fn payload_type_index(&mut self, ty: TypeId, imported: bool) -> Result<u32> {
-        // `stream` and `future` types don't have owners, but their payload
-        // types (or the payload type of the payload type, etc. in the case of
-        // nesting) might have an owner, in which case we need to find that in
-        // order to make the types match up e.g. when we're exporting a resource
-        // that's used as a payload type.
-        fn owner(resolve: &Resolve, ty: TypeId) -> Option<InterfaceId> {
-            let def = &resolve.types[ty];
-            match &def.kind {
-                TypeDefKind::Future(Some(Type::Id(ty)))
-                | TypeDefKind::Stream(Some(Type::Id(ty))) => owner(resolve, *ty),
-                _ => match &def.owner {
-                    TypeOwner::World(_) | TypeOwner::None => None,
-                    TypeOwner::Interface(id) => Some(*id),
-                },
-            }
-        }
-
+    fn payload_type_index(&mut self, info: &PayloadInfo) -> Result<u32> {
         let resolve = &self.info.encoder.metadata.resolve;
-        let ComponentValType::Type(type_index) = if imported {
-            self.root_import_type_encoder(None)
+        let ComponentValType::Type(type_index) = if info.imported {
+            self.root_import_type_encoder(info.interface)
         } else {
-            let owner = owner(resolve, ty);
-            self.root_export_type_encoder(owner)
+            self.root_export_type_encoder(info.interface)
         }
-        .encode_valtype(resolve, &Type::Id(ty))?
+        .encode_valtype(resolve, &Type::Id(info.ty))?
         else {
             unreachable!()
         };
@@ -1609,10 +1590,10 @@ impl<'a> EncodingState<'a> {
                     AbiVariant::GuestImport,
                 )
             }
-            Import::ExportedTaskReturn(interface, function) => {
+            Import::ExportedTaskReturn(interface, _function, result) => {
                 let mut encoder = self.root_export_type_encoder(*interface);
 
-                let result = match &function.result {
+                let result = match result {
                     Some(ty) => Some(encoder.encode_valtype(resolve, ty)?),
                     None => None,
                 };
@@ -1639,96 +1620,76 @@ impl<'a> EncodingState<'a> {
                 Ok((ExportKind::Func, index))
             }
             Import::StreamNew(info) => {
-                let ty = self.payload_type_index(info.ty, info.imported)?;
+                let ty = self.payload_type_index(info)?;
                 let index = self.component.stream_new(ty);
                 Ok((ExportKind::Func, index))
             }
-            Import::StreamRead { async_, info } => Ok(self.materialize_payload_import(
+            Import::StreamRead { info, .. } => Ok(self.materialize_payload_import(
                 shims,
                 for_module,
-                *async_,
                 info,
                 PayloadFuncKind::StreamRead,
             )),
-            Import::StreamWrite { async_, info } => Ok(self.materialize_payload_import(
+            Import::StreamWrite { info, .. } => Ok(self.materialize_payload_import(
                 shims,
                 for_module,
-                *async_,
                 info,
                 PayloadFuncKind::StreamWrite,
             )),
-            Import::StreamCancelRead {
-                ty,
-                imported,
-                async_,
-            } => {
-                let ty = self.payload_type_index(*ty, *imported)?;
+            Import::StreamCancelRead { info, async_ } => {
+                let ty = self.payload_type_index(info)?;
                 let index = self.component.stream_cancel_read(ty, *async_);
                 Ok((ExportKind::Func, index))
             }
-            Import::StreamCancelWrite {
-                ty,
-                imported,
-                async_,
-            } => {
-                let ty = self.payload_type_index(*ty, *imported)?;
+            Import::StreamCancelWrite { info, async_ } => {
+                let ty = self.payload_type_index(info)?;
                 let index = self.component.stream_cancel_write(ty, *async_);
                 Ok((ExportKind::Func, index))
             }
-            Import::StreamCloseReadable { ty, imported } => {
-                let type_index = self.payload_type_index(*ty, *imported)?;
+            Import::StreamCloseReadable(info) => {
+                let type_index = self.payload_type_index(info)?;
                 let index = self.component.stream_close_readable(type_index);
                 Ok((ExportKind::Func, index))
             }
-            Import::StreamCloseWritable { ty, imported } => {
-                let type_index = self.payload_type_index(*ty, *imported)?;
+            Import::StreamCloseWritable(info) => {
+                let type_index = self.payload_type_index(info)?;
                 let index = self.component.stream_close_writable(type_index);
                 Ok((ExportKind::Func, index))
             }
             Import::FutureNew(info) => {
-                let ty = self.payload_type_index(info.ty, info.imported)?;
+                let ty = self.payload_type_index(info)?;
                 let index = self.component.future_new(ty);
                 Ok((ExportKind::Func, index))
             }
-            Import::FutureRead { async_, info } => Ok(self.materialize_payload_import(
+            Import::FutureRead { info, .. } => Ok(self.materialize_payload_import(
                 shims,
                 for_module,
-                *async_,
                 info,
                 PayloadFuncKind::FutureRead,
             )),
-            Import::FutureWrite { async_, info } => Ok(self.materialize_payload_import(
+            Import::FutureWrite { info, .. } => Ok(self.materialize_payload_import(
                 shims,
                 for_module,
-                *async_,
                 info,
                 PayloadFuncKind::FutureWrite,
             )),
-            Import::FutureCancelRead {
-                ty,
-                imported,
-                async_,
-            } => {
-                let ty = self.payload_type_index(*ty, *imported)?;
+            Import::FutureCancelRead { info, async_ } => {
+                let ty = self.payload_type_index(info)?;
                 let index = self.component.future_cancel_read(ty, *async_);
                 Ok((ExportKind::Func, index))
             }
-            Import::FutureCancelWrite {
-                ty,
-                imported,
-                async_,
-            } => {
-                let ty = self.payload_type_index(*ty, *imported)?;
+            Import::FutureCancelWrite { info, async_ } => {
+                let ty = self.payload_type_index(info)?;
                 let index = self.component.future_cancel_write(ty, *async_);
                 Ok((ExportKind::Func, index))
             }
-            Import::FutureCloseReadable { ty, imported } => {
-                let type_index = self.payload_type_index(*ty, *imported)?;
+            Import::FutureCloseReadable(info) => {
+                let type_index = self.payload_type_index(info)?;
                 let index = self.component.future_close_readable(type_index);
                 Ok((ExportKind::Func, index))
             }
-            Import::FutureCloseWritable { ty, imported } => {
-                let type_index = self.payload_type_index(*ty, *imported)?;
+            Import::FutureCloseWritable(info) => {
+                let type_index = self.payload_type_index(info)?;
                 let index = self.component.future_close_writable(type_index);
                 Ok((ExportKind::Func, index))
             }
@@ -1783,7 +1744,6 @@ impl<'a> EncodingState<'a> {
         &mut self,
         shims: &Shims<'_>,
         for_module: CustomModule<'_>,
-        async_: bool,
         info: &PayloadInfo,
         kind: PayloadFuncKind,
     ) -> (ExportKind, u32) {
@@ -1791,7 +1751,6 @@ impl<'a> EncodingState<'a> {
             shims,
             &ShimKind::PayloadFunc {
                 for_module,
-                async_,
                 info,
                 kind,
             },
@@ -2033,8 +1992,6 @@ enum ShimKind<'a> {
         /// Which instance to pull the `realloc` function and string encoding
         /// from, if necessary.
         for_module: CustomModule<'a>,
-        /// Whether this read/write call is using the `async` option.
-        async_: bool,
         /// Additional information regarding the function where this `stream` or
         /// `future` type appeared, which we use in combination with
         /// `for_module` to determine which `realloc` and string encoding to
@@ -2387,7 +2344,6 @@ impl<'a> Shims<'a> {
                 ),
             kind: ShimKind::PayloadFunc {
                 for_module,
-                async_,
                 info,
                 kind,
             },
diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs
index 88a4e8ee..9dbf5aa5 100644
--- a/crates/wit-component/src/validation.rs
+++ b/crates/wit-component/src/validation.rs
@@ -1,6 +1,6 @@
 use crate::encoding::{Instance, Item, LibraryInfo, MainOrAdapter};
 use crate::{ComponentEncoder, StringEncoding};
-use anyhow::{bail, Context, Result};
+use anyhow::{anyhow, bail, Context, Result};
 use indexmap::{map::Entry, IndexMap, IndexSet};
 use std::hash::{Hash, Hasher};
 use std::mem;
@@ -142,7 +142,7 @@ pub struct PayloadInfo {
     pub ty: TypeId,
     /// The component-level function import or export where the type appeared as
     /// a parameter or result type.
-    pub function: Function,
+    pub function: String,
     /// The world key representing the import or export context of `function`.
     pub key: WorldKey,
     /// The interface that `function` was imported from or exported in, if any.
@@ -253,7 +253,7 @@ pub enum Import {
     /// As of this writing, only async-lifted exports use `task.return`, but the
     /// plan is to also support it for sync-lifted exports in the future as
     /// well.
-    ExportedTaskReturn(Option<InterfaceId>, Function),
+    ExportedTaskReturn(Option<InterfaceId>, String, Option<Type>),
 
     /// A `canon task.backpressure` intrinsic.
     ///
@@ -307,31 +307,23 @@ pub enum Import {
     ///
     /// This allows the guest to cancel a pending read it initiated earlier (but
     /// which may have already partially or entirely completed).
-    StreamCancelRead {
-        ty: TypeId,
-        imported: bool,
-        async_: bool,
-    },
+    StreamCancelRead { info: PayloadInfo, async_: bool },
 
     /// A `canon stream.cancel-write` intrinsic.
     ///
     /// This allows the guest to cancel a pending write it initiated earlier
     /// (but which may have already partially or entirely completed).
-    StreamCancelWrite {
-        ty: TypeId,
-        imported: bool,
-        async_: bool,
-    },
+    StreamCancelWrite { info: PayloadInfo, async_: bool },
 
     /// A `canon stream.close-readable` intrinsic.
     ///
     /// This allows the guest to close the readable end of a `stream`.
-    StreamCloseReadable { ty: TypeId, imported: bool },
+    StreamCloseReadable(PayloadInfo),
 
     /// A `canon stream.close-writable` intrinsic.
     ///
     /// This allows the guest to close the writable end of a `stream`.
-    StreamCloseWritable { ty: TypeId, imported: bool },
+    StreamCloseWritable(PayloadInfo),
 
     /// A `canon future.new` intrinsic.
     ///
@@ -353,31 +345,23 @@ pub enum Import {
     ///
     /// This allows the guest to cancel a pending read it initiated earlier (but
     /// which may have already completed).
-    FutureCancelRead {
-        ty: TypeId,
-        imported: bool,
-        async_: bool,
-    },
+    FutureCancelRead { info: PayloadInfo, async_: bool },
 
     /// A `canon future.cancel-write` intrinsic.
     ///
     /// This allows the guest to cancel a pending write it initiated earlier
     /// (but which may have already completed).
-    FutureCancelWrite {
-        ty: TypeId,
-        imported: bool,
-        async_: bool,
-    },
+    FutureCancelWrite { info: PayloadInfo, async_: bool },
 
     /// A `canon future.close-readable` intrinsic.
     ///
     /// This allows the guest to close the readable end of a `future`.
-    FutureCloseReadable { ty: TypeId, imported: bool },
+    FutureCloseReadable(PayloadInfo),
 
     /// A `canon future.close-writable` intrinsic.
     ///
     /// This allows the guest to close the writable end of a `future`.
-    FutureCloseWritable { ty: TypeId, imported: bool },
+    FutureCloseWritable(PayloadInfo),
 
     /// A `canon error-context.new` intrinsic.
     ///
@@ -548,29 +532,15 @@ impl ImportMap {
         let world_id = encoder.metadata.world;
         let world = &resolve.worlds[world_id];
 
-        if let Some(import) = names.payload_import(module, name, resolve, world, ty)? {
-            return Ok(import);
-        }
-
-        let async_import_for_export = |interface: Option<(WorldKey, InterfaceId)>| {
-            Ok::<_, anyhow::Error>(if let Some(function_name) = names.task_return_name(name) {
-                let interface_id = interface.as_ref().map(|(_, id)| *id);
-                let func = get_function(resolve, world, function_name, interface_id, false)?;
-                // Note that we can't statically validate the type signature of
-                // a `task.return` built-in since we can't know which export
-                // it's associated with in general.  Instead, the host will
-                // compare it with the expected type at runtime and trap if
-                // necessary.
-                Some(Import::ExportedTaskReturn(interface_id, func))
-            } else {
-                None
-            })
+        let (async_, name) = if let Some(name) = names.async_name(name) {
+            (true, name)
+        } else {
+            (false, name)
         };
-
-        let (abi, name) = if let Some(name) = names.async_name(name) {
-            (AbiVariant::GuestImportAsync, name)
+        let abi = if async_ {
+            AbiVariant::GuestImportAsync
         } else {
-            (AbiVariant::GuestImport, name)
+            AbiVariant::GuestImport
         };
 
         if module == names.import_root() {
@@ -637,13 +607,10 @@ impl ImportMap {
                 return Ok(Import::WorldFunc(key, func.name.clone(), abi));
             }
 
-            let get_resource = resource_test_for_world(resolve, world_id);
-            if let Some(resource) = names.resource_drop_name(name) {
-                if let Some(id) = get_resource(resource) {
-                    let expected = FuncType::new([ValType::I32], []);
-                    validate_func_sig(name, &expected, ty)?;
-                    return Ok(Import::ImportedResourceDrop(key, None, id));
-                }
+            if let Some(import) =
+                self.maybe_classify_wit_intrinsic(name, None, encoder, ty, async_, true, names)?
+            {
+                return Ok(import);
             }
 
             match world.imports.get(&key) {
@@ -652,11 +619,14 @@ impl ImportMap {
             }
         }
 
+        // Check for `[export]$root::[task-return]foo` or similar
         if matches!(
             module.strip_prefix(names.import_exported_intrinsic_prefix()),
             Some(module) if module == names.import_root()
         ) {
-            if let Some(import) = async_import_for_export(None)? {
+            if let Some(import) =
+                self.maybe_classify_wit_intrinsic(name, None, encoder, ty, async_, false, names)?
+            {
                 return Ok(import);
             }
         }
@@ -667,56 +637,42 @@ impl ImportMap {
         };
 
         if let Some(interface) = interface.strip_prefix(names.import_exported_intrinsic_prefix()) {
-            if let Some(import) = async_import_for_export(Some(names.module_to_interface(
-                interface,
-                resolve,
-                &world.exports,
-            )?))? {
-                return Ok(import);
-            }
-
             let (key, id) = names.module_to_interface(interface, resolve, &world.exports)?;
 
-            let get_resource = resource_test_for_interface(resolve, id);
-            if let Some(name) = names.resource_drop_name(name) {
-                if let Some(id) = get_resource(name) {
-                    let expected = FuncType::new([ValType::I32], []);
-                    validate_func_sig(name, &expected, ty)?;
-                    return Ok(Import::ExportedResourceDrop(key, id));
-                }
-            }
-            if let Some(name) = names.resource_new_name(name) {
-                if let Some(id) = get_resource(name) {
-                    let expected = FuncType::new([ValType::I32], [ValType::I32]);
-                    validate_func_sig(name, &expected, ty)?;
-                    return Ok(Import::ExportedResourceNew(key, id));
-                }
-            }
-            if let Some(name) = names.resource_rep_name(name) {
-                if let Some(id) = get_resource(name) {
-                    let expected = FuncType::new([ValType::I32], [ValType::I32]);
-                    validate_func_sig(name, &expected, ty)?;
-                    return Ok(Import::ExportedResourceRep(key, id));
-                }
+            if let Some(import) = self.maybe_classify_wit_intrinsic(
+                name,
+                Some((key, id)),
+                encoder,
+                ty,
+                async_,
+                false,
+                names,
+            )? {
+                return Ok(import);
             }
             bail!("unknown function `{name}`")
         }
 
         let (key, id) = names.module_to_interface(interface, resolve, &world.imports)?;
         let interface = &resolve.interfaces[id];
-        let get_resource = resource_test_for_interface(resolve, id);
         if let Some(f) = interface.functions.get(name) {
             validate_func(resolve, ty, f, abi).with_context(|| {
                 let name = resolve.name_world_key(&key);
                 format!("failed to validate import interface `{name}`")
             })?;
             return Ok(Import::InterfaceFunc(key, id, f.name.clone(), abi));
-        } else if let Some(resource) = names.resource_drop_name(name) {
-            if let Some(resource) = get_resource(resource) {
-                let expected = FuncType::new([ValType::I32], []);
-                validate_func_sig(name, &expected, ty)?;
-                return Ok(Import::ImportedResourceDrop(key, Some(id), resource));
-            }
+        }
+
+        if let Some(import) = self.maybe_classify_wit_intrinsic(
+            name,
+            Some((key, id)),
+            encoder,
+            ty,
+            async_,
+            true,
+            names,
+        )? {
+            return Ok(import);
         }
         bail!(
             "import interface `{module}` is missing function \
@@ -724,6 +680,214 @@ impl ImportMap {
         )
     }
 
+    /// Attempts to detect and classify `name` as a WIT intrinsic.
+    ///
+    /// This function is a bit of a sprawling sequence of matches used to
+    /// detect whether `name` corresponds to a WIT intrinsic, so specifically
+    /// not a WIT function itself. This is only used for functions imported
+    /// into a module but the import could be for an imported item in a world
+    /// or an exported item.
+    ///
+    /// ## Parameters
+    ///
+    /// * `name` - the core module name which is being pattern-matched. This
+    ///   should be the "field" of the import. This should have the "[async]"
+    ///   prefix stripped out already.
+    /// * `key_and_id` - this is the inferred "container" for the function
+    ///   being described which is inferred from the module portion of the core
+    ///   wasm import field. This is `None` for root-level function/type
+    ///   imports, such as when referring to `import x: func();`. This is `Some`
+    ///   when an interface is used (either `import x: interface { .. }` or a
+    ///   standalone `interface`) where the world key is specified for the
+    ///   interface in addition to the interface that was identified.
+    /// * `encoder` - this is the encoder state that contains
+    ///   `Resolve`/metadata information.
+    /// * `ty` - the core wasm type of this import.
+    /// * `async_` - whether or not this import had the `[async]` import. Note
+    ///   that such prefix is not present in `name`.
+    /// * `import` - whether or not this core wasm import is operating on a WIT
+    ///   level import or export. An example of this being an export is when a
+    ///   core module imports a destructor for an exported resource.
+    /// * `names` - the name mangling scheme that's configured to be used.
+    fn maybe_classify_wit_intrinsic(
+        &self,
+        name: &str,
+        key_and_id: Option<(WorldKey, InterfaceId)>,
+        encoder: &ComponentEncoder,
+        ty: &FuncType,
+        async_: bool,
+        import: bool,
+        names: &dyn NameMangling,
+    ) -> Result<Option<Import>> {
+        let resolve = &encoder.metadata.resolve;
+        let world_id = encoder.metadata.world;
+        let world = &resolve.worlds[world_id];
+
+        // Separate out `Option<WorldKey>` and `Option<InterfaceId>`. If an
+        // interface is NOT specified then the `WorldKey` which is attached to
+        // imports is going to be calculated based on the name of the item
+        // extracted, such as the resource or function referenced.
+        let (key, id) = match key_and_id {
+            Some((key, id)) => (Some(key), Some(id)),
+            None => (None, None),
+        };
+
+        // Tests whether `name` is a resource within `id` (or `world_id`).
+        let resource_test = |name: &str| match id {
+            Some(id) => resource_test_for_interface(resolve, id)(name),
+            None => resource_test_for_world(resolve, world_id)(name),
+        };
+
+        // Test whether this is a `resource.drop` intrinsic.
+        if let Some(resource) = names.resource_drop_name(name) {
+            if async_ {
+                bail!("async `resource.drop` calls not supported");
+            }
+            if let Some(resource_id) = resource_test(resource) {
+                let key = key.unwrap_or_else(|| WorldKey::Name(resource.to_string()));
+                let expected = FuncType::new([ValType::I32], []);
+                validate_func_sig(name, &expected, ty)?;
+                return Ok(Some(if import {
+                    Import::ImportedResourceDrop(key, id, resource_id)
+                } else {
+                    Import::ExportedResourceDrop(key, resource_id)
+                }));
+            }
+        }
+
+        // There are some intrinsics which are only applicable to exported
+        // functions/resources, so check those use cases here.
+        if !import {
+            if let Some(name) = names.resource_new_name(name) {
+                if let Some(id) = resource_test(name) {
+                    let key = key.unwrap_or_else(|| WorldKey::Name(name.to_string()));
+                    let expected = FuncType::new([ValType::I32], [ValType::I32]);
+                    validate_func_sig(name, &expected, ty)?;
+                    return Ok(Some(Import::ExportedResourceNew(key, id)));
+                }
+            }
+            if let Some(name) = names.resource_rep_name(name) {
+                if let Some(id) = resource_test(name) {
+                    let key = key.unwrap_or_else(|| WorldKey::Name(name.to_string()));
+                    let expected = FuncType::new([ValType::I32], [ValType::I32]);
+                    validate_func_sig(name, &expected, ty)?;
+                    return Ok(Some(Import::ExportedResourceRep(key, id)));
+                }
+            }
+            if let Some(name) = names.task_return_name(name) {
+                let func = get_function(resolve, world, name, id, import)?;
+                // TODO: should call `validate_func_sig` but would require
+                // calculating the expected signature based of `func.result`.
+                return Ok(Some(Import::ExportedTaskReturn(
+                    None,
+                    func.name.clone(),
+                    func.result,
+                )));
+            }
+        }
+
+        // Looks for `[$prefix-N]foo` within `name`. If found then `foo` is
+        // used to find a function within `id` and `world` above. Once found
+        // then `N` is used to index within that function to extract a
+        // future/stream type. If that's all found then a `PayloadInfo` is
+        // returned to get attached to an intrinsic.
+        let prefixed_payload = |prefix: &str| {
+            // parse the `prefix` into `func_name` and `type_index`, bailing out
+            // with `None` if anything doesn't match.
+            let suffix = name.strip_prefix(prefix)?;
+            let index = suffix.find(']')?;
+            let func_name = &suffix[index + 1..];
+            let type_index: usize = suffix[..index].parse().ok()?;
+
+            // Double-check that `func_name` is indeed a function name within
+            // this interface/world. Then additionally double-check that
+            // `type_index` is indeed a valid index for this function's type
+            // signature.
+            let function = get_function(resolve, world, func_name, id, import).ok()?;
+            let ty = *function.find_futures_and_streams(resolve).get(type_index)?;
+
+            // And if all that passes wrap up everything in a `PayloadInfo`.
+            Some(PayloadInfo {
+                name: name.to_string(),
+                ty,
+                function: function.name.clone(),
+                key: key
+                    .clone()
+                    .unwrap_or_else(|| WorldKey::Name(name.to_string())),
+                interface: id,
+                imported: import,
+            })
+        };
+
+        // Test for a number of async-related intrinsics. All intrinsics are
+        // prefixed with `[...-N]` where `...` is the name of the intrinsic and
+        // the `N` is the indexed future/stream that is being referred to.
+        let import = if let Some(info) = prefixed_payload("[future-new-") {
+            if async_ {
+                bail!("async `future.new` calls not supported");
+            }
+            validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?;
+            Import::FutureNew(info)
+        } else if let Some(info) = prefixed_payload("[future-write-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?;
+            Import::FutureWrite { async_, info }
+        } else if let Some(info) = prefixed_payload("[future-read-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?;
+            Import::FutureRead { async_, info }
+        } else if let Some(info) = prefixed_payload("[future-cancel-write-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?;
+            Import::FutureCancelWrite { async_, info }
+        } else if let Some(info) = prefixed_payload("[future-cancel-read-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?;
+            Import::FutureCancelRead { async_, info }
+        } else if let Some(info) = prefixed_payload("[future-close-writable-") {
+            if async_ {
+                bail!("async `future.close-writable` calls not supported");
+            }
+            validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
+            Import::FutureCloseWritable(info)
+        } else if let Some(info) = prefixed_payload("[future-close-readable-") {
+            if async_ {
+                bail!("async `future.close-readable` calls not supported");
+            }
+            validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
+            Import::FutureCloseReadable(info)
+        } else if let Some(info) = prefixed_payload("[stream-new-") {
+            if async_ {
+                bail!("async `stream.new` calls not supported");
+            }
+            validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?;
+            Import::StreamNew(info)
+        } else if let Some(info) = prefixed_payload("[stream-write-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?;
+            Import::StreamWrite { async_, info }
+        } else if let Some(info) = prefixed_payload("[stream-read-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?;
+            Import::StreamRead { async_, info }
+        } else if let Some(info) = prefixed_payload("[stream-cancel-write-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?;
+            Import::StreamCancelWrite { async_, info }
+        } else if let Some(info) = prefixed_payload("[stream-cancel-read-") {
+            validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?;
+            Import::StreamCancelRead { async_, info }
+        } else if let Some(info) = prefixed_payload("[stream-close-writable-") {
+            if async_ {
+                bail!("async `stream.close-writable` calls not supported");
+            }
+            validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
+            Import::StreamCloseWritable(info)
+        } else if let Some(info) = prefixed_payload("[stream-close-readable-") {
+            if async_ {
+                bail!("async `stream.close-readable` calls not supported");
+            }
+            validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
+            Import::StreamCloseReadable(info)
+        } else {
+            return Ok(None);
+        };
+        Ok(Some(import))
+    }
+
     fn classify_import_with_library(
         &mut self,
         import: wasmparser::Import<'_>,
@@ -1043,7 +1207,7 @@ impl ExportMap {
 
     /// Returns the realloc that the exported function `interface` and `func`
     /// are using.
-    pub fn export_realloc_for(&self, key: &WorldKey, func: &Function) -> Option<&str> {
+    pub fn export_realloc_for(&self, key: &WorldKey, func: &str) -> Option<&str> {
         // TODO: This realloc detection should probably be improved with
         // some sort of scheme to have per-function reallocs like
         // `cabi_realloc_{name}` or something like that.
@@ -1211,14 +1375,6 @@ trait NameMangling {
     fn error_context_new(&self, s: &str) -> Option<StringEncoding>;
     fn error_context_debug_message<'a>(&self, s: &'a str) -> Option<(StringEncoding, &'a str)>;
     fn error_context_drop(&self) -> Option<&str>;
-    fn payload_import(
-        &self,
-        module: &str,
-        name: &str,
-        resolve: &Resolve,
-        world: &World,
-        ty: &FuncType,
-    ) -> Result<Option<Import>>;
     fn module_to_interface(
         &self,
         module: &str,
@@ -1318,17 +1474,6 @@ impl NameMangling for Standard {
     fn error_context_drop(&self) -> Option<&str> {
         None
     }
-    fn payload_import(
-        &self,
-        module: &str,
-        name: &str,
-        resolve: &Resolve,
-        world: &World,
-        ty: &FuncType,
-    ) -> Result<Option<Import>> {
-        _ = (module, name, resolve, world, ty);
-        Ok(None)
-    }
     fn module_to_interface(
         &self,
         interface: &str,
@@ -1526,215 +1671,6 @@ impl NameMangling for Legacy {
     fn error_context_drop(&self) -> Option<&str> {
         Some("[error-context-drop]")
     }
-    fn payload_import(
-        &self,
-        module: &str,
-        name: &str,
-        resolve: &Resolve,
-        world: &World,
-        ty: &FuncType,
-    ) -> Result<Option<Import>> {
-        Ok(
-            if let Some((suffix, imported)) = module
-                .strip_prefix("[import-payload]")
-                .map(|v| (v, true))
-                .or_else(|| module.strip_prefix("[export-payload]").map(|v| (v, false)))
-            {
-                let (key, interface) = if suffix == self.import_root() {
-                    (WorldKey::Name(name.to_string()), None)
-                } else {
-                    let (key, id) = self.module_to_interface(
-                        suffix,
-                        resolve,
-                        if imported {
-                            &world.imports
-                        } else {
-                            &world.exports
-                        },
-                    )?;
-                    (key, Some(id))
-                };
-
-                let orig_name = name;
-
-                let (name, async_) = if let Some(name) = self.async_name(name) {
-                    (name, true)
-                } else {
-                    (name, false)
-                };
-
-                let info = |payload_key| {
-                    let (function, ty) = get_future_or_stream_type(
-                        resolve,
-                        world,
-                        &payload_key,
-                        interface,
-                        imported,
-                    )?;
-                    Ok::<_, anyhow::Error>(PayloadInfo {
-                        name: orig_name.to_string(),
-                        ty,
-                        function,
-                        key: key.clone(),
-                        interface,
-                        imported,
-                    })
-                };
-
-                Some(
-                    if let Some(key) = match_payload_prefix(name, "[future-new-") {
-                        if async_ {
-                            bail!("async `future.new` calls not supported");
-                        }
-                        validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?;
-                        Import::FutureNew(info(key)?)
-                    } else if let Some(key) = match_payload_prefix(name, "[future-write-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32; 2], [ValType::I32]),
-                            ty,
-                        )?;
-                        Import::FutureWrite {
-                            async_,
-                            info: info(key)?,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[future-read-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32; 2], [ValType::I32]),
-                            ty,
-                        )?;
-                        Import::FutureRead {
-                            async_,
-                            info: info(key)?,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[future-cancel-write-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32], [ValType::I32]),
-                            ty,
-                        )?;
-                        let info = info(key)?;
-                        Import::FutureCancelWrite {
-                            async_,
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[future-cancel-read-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32], [ValType::I32]),
-                            ty,
-                        )?;
-                        let info = info(key)?;
-                        Import::FutureCancelRead {
-                            async_,
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[future-close-writable-")
-                    {
-                        if async_ {
-                            bail!("async `future.close-writable` calls not supported");
-                        }
-                        validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
-                        let info = info(key)?;
-                        Import::FutureCloseWritable {
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[future-close-readable-")
-                    {
-                        if async_ {
-                            bail!("async `future.close-readable` calls not supported");
-                        }
-                        validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
-                        let info = info(key)?;
-                        Import::FutureCloseReadable {
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-new-") {
-                        if async_ {
-                            bail!("async `stream.new` calls not supported");
-                        }
-                        validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?;
-                        Import::StreamNew(info(key)?)
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-write-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32; 3], [ValType::I32]),
-                            ty,
-                        )?;
-                        Import::StreamWrite {
-                            async_,
-                            info: info(key)?,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-read-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32; 3], [ValType::I32]),
-                            ty,
-                        )?;
-                        Import::StreamRead {
-                            async_,
-                            info: info(key)?,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-write-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32], [ValType::I32]),
-                            ty,
-                        )?;
-                        let info = info(key)?;
-                        Import::StreamCancelWrite {
-                            async_,
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-read-") {
-                        validate_func_sig(
-                            name,
-                            &FuncType::new([ValType::I32], [ValType::I32]),
-                            ty,
-                        )?;
-                        let info = info(key)?;
-                        Import::StreamCancelRead {
-                            async_,
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-close-writable-")
-                    {
-                        if async_ {
-                            bail!("async `stream.close-writable` calls not supported");
-                        }
-                        validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?;
-                        let info = info(key)?;
-                        Import::StreamCloseWritable {
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else if let Some(key) = match_payload_prefix(name, "[stream-close-readable-")
-                    {
-                        if async_ {
-                            bail!("async `stream.close-readable` calls not supported");
-                        }
-                        validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?;
-                        let info = info(key)?;
-                        Import::StreamCloseReadable {
-                            ty: info.ty,
-                            imported: info.imported,
-                        }
-                    } else {
-                        bail!("unrecognized payload import: {name}");
-                    },
-                )
-            } else {
-                None
-            },
-        )
-    }
     fn module_to_interface(
         &self,
         module: &str,
@@ -2020,55 +1956,22 @@ fn validate_func_sig(name: &str, expected: &FuncType, ty: &wasmparser::FuncType)
     Ok(())
 }
 
-fn match_payload_prefix(name: &str, prefix: &str) -> Option<(String, usize)> {
-    let suffix = name.strip_prefix(prefix)?;
-    let index = suffix.find(']')?;
-    Some((
-        suffix[index + 1..].to_owned(),
-        suffix[..index].parse().ok()?,
-    ))
-}
-
-/// Retrieve the specified function from the specified world or interface, along
-/// with the future or stream type at the specified index.
-///
-/// The index refers to the entry in the list returned by
-/// `Function::find_futures_and_streams`.
-fn get_future_or_stream_type(
-    resolve: &Resolve,
-    world: &World,
-    (name, index): &(String, usize),
-    interface: Option<InterfaceId>,
-    imported: bool,
-) -> Result<(Function, TypeId)> {
-    let function = get_function(resolve, world, name, interface, imported)?;
-    let ty = function.find_futures_and_streams(resolve)[*index];
-    Ok((function, ty))
-}
-
-fn get_function(
-    resolve: &Resolve,
-    world: &World,
+fn get_function<'a>(
+    resolve: &'a Resolve,
+    world: &'a World,
     name: &str,
     interface: Option<InterfaceId>,
     imported: bool,
-) -> Result<Function> {
+) -> Result<&'a Function> {
     let function = if let Some(id) = interface {
-        resolve.interfaces[id]
+        return resolve.interfaces[id]
             .functions
             .get(name)
-            .cloned()
-            .map(WorldItem::Function)
+            .ok_or_else(|| anyhow!("no export `{name}` found"));
     } else if imported {
-        world
-            .imports
-            .get(&WorldKey::Name(name.to_string()))
-            .cloned()
+        world.imports.get(&WorldKey::Name(name.to_string()))
     } else {
-        world
-            .exports
-            .get(&WorldKey::Name(name.to_string()))
-            .cloned()
+        world.exports.get(&WorldKey::Name(name.to_string()))
     };
     let Some(WorldItem::Function(function)) = function else {
         bail!("no export `{name}` found");


Test patch:
diff --git a/crates/wit-component/tests/components/async-streams-and-futures/component.wat b/crates/wit-component/tests/components/async-streams-and-futures/component.wat
index d5ee9787..4e0883c6 100644
--- a/crates/wit-component/tests/components/async-streams-and-futures/component.wat
+++ b/crates/wit-component/tests/components/async-streams-and-futures/component.wat
@@ -24,90 +24,90 @@
     (type (;6;) (func (param i32 i32 i32 i32) (result i32)))
     (import "$root" "[async]foo" (func (;0;) (type 0)))
     (import "foo:foo/bar" "[async]foo" (func (;1;) (type 0)))
-    (import "[import-payload]$root" "[stream-new-2]foo" (func (;2;) (type 1)))
-    (import "[import-payload]$root" "[stream-read-2]foo" (func (;3;) (type 2)))
-    (import "[import-payload]$root" "[stream-write-2]foo" (func (;4;) (type 2)))
-    (import "[import-payload]$root" "[stream-cancel-read-2]foo" (func (;5;) (type 3)))
-    (import "[import-payload]$root" "[stream-cancel-write-2]foo" (func (;6;) (type 3)))
-    (import "[import-payload]$root" "[stream-close-readable-2]foo" (func (;7;) (type 4)))
-    (import "[import-payload]$root" "[stream-close-writable-2]foo" (func (;8;) (type 5)))
-    (import "[import-payload]foo:foo/bar" "[stream-new-2]foo" (func (;9;) (type 1)))
-    (import "[import-payload]foo:foo/bar" "[stream-read-2]foo" (func (;10;) (type 2)))
-    (import "[import-payload]foo:foo/bar" "[stream-write-2]foo" (func (;11;) (type 2)))
-    (import "[import-payload]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;12;) (type 3)))
-    (import "[import-payload]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;13;) (type 3)))
-    (import "[import-payload]foo:foo/bar" "[stream-close-readable-2]foo" (func (;14;) (type 4)))
-    (import "[import-payload]foo:foo/bar" "[stream-close-writable-2]foo" (func (;15;) (type 5)))
-    (import "[import-payload]$root" "[future-new-0]foo" (func (;16;) (type 1)))
-    (import "[import-payload]$root" "[future-read-0]foo" (func (;17;) (type 0)))
-    (import "[import-payload]$root" "[future-write-0]foo" (func (;18;) (type 0)))
-    (import "[import-payload]$root" "[future-cancel-read-0]foo" (func (;19;) (type 3)))
-    (import "[import-payload]$root" "[future-cancel-write-0]foo" (func (;20;) (type 3)))
-    (import "[import-payload]$root" "[future-close-readable-0]foo" (func (;21;) (type 4)))
-    (import "[import-payload]$root" "[future-close-writable-0]foo" (func (;22;) (type 5)))
-    (import "[import-payload]foo:foo/bar" "[future-new-0]foo" (func (;23;) (type 1)))
-    (import "[import-payload]foo:foo/bar" "[future-read-0]foo" (func (;24;) (type 0)))
-    (import "[import-payload]foo:foo/bar" "[future-write-0]foo" (func (;25;) (type 0)))
-    (import "[import-payload]foo:foo/bar" "[future-cancel-read-0]foo" (func (;26;) (type 3)))
-    (import "[import-payload]foo:foo/bar" "[future-cancel-write-0]foo" (func (;27;) (type 3)))
-    (import "[import-payload]foo:foo/bar" "[future-close-readable-0]foo" (func (;28;) (type 4)))
-    (import "[import-payload]foo:foo/bar" "[future-close-writable-0]foo" (func (;29;) (type 5)))
-    (import "[import-payload]$root" "[future-new-1]foo" (func (;30;) (type 1)))
-    (import "[import-payload]$root" "[future-read-1]foo" (func (;31;) (type 0)))
-    (import "[import-payload]$root" "[future-write-1]foo" (func (;32;) (type 0)))
-    (import "[import-payload]$root" "[future-cancel-read-1]foo" (func (;33;) (type 3)))
-    (import "[import-payload]$root" "[future-cancel-write-1]foo" (func (;34;) (type 3)))
-    (import "[import-payload]$root" "[future-close-readable-1]foo" (func (;35;) (type 4)))
-    (import "[import-payload]$root" "[future-close-writable-1]foo" (func (;36;) (type 5)))
-    (import "[import-payload]foo:foo/bar" "[future-new-1]foo" (func (;37;) (type 1)))
-    (import "[import-payload]foo:foo/bar" "[future-read-1]foo" (func (;38;) (type 0)))
-    (import "[import-payload]foo:foo/bar" "[future-write-1]foo" (func (;39;) (type 0)))
-    (import "[import-payload]foo:foo/bar" "[future-cancel-read-1]foo" (func (;40;) (type 3)))
-    (import "[import-payload]foo:foo/bar" "[future-cancel-write-1]foo" (func (;41;) (type 3)))
-    (import "[import-payload]foo:foo/bar" "[future-close-readable-1]foo" (func (;42;) (type 4)))
-    (import "[import-payload]foo:foo/bar" "[future-close-writable-1]foo" (func (;43;) (type 5)))
-    (import "[export-payload]$root" "[stream-new-2]foo" (func (;44;) (type 1)))
-    (import "[export-payload]$root" "[stream-read-2]foo" (func (;45;) (type 2)))
-    (import "[export-payload]$root" "[stream-write-2]foo" (func (;46;) (type 2)))
-    (import "[export-payload]$root" "[stream-cancel-read-2]foo" (func (;47;) (type 3)))
-    (import "[export-payload]$root" "[stream-cancel-write-2]foo" (func (;48;) (type 3)))
-    (import "[export-payload]$root" "[stream-close-readable-2]foo" (func (;49;) (type 4)))
-    (import "[export-payload]$root" "[stream-close-writable-2]foo" (func (;50;) (type 5)))
-    (import "[export-payload]foo:foo/bar" "[stream-new-2]foo" (func (;51;) (type 1)))
-    (import "[export-payload]foo:foo/bar" "[stream-read-2]foo" (func (;52;) (type 2)))
-    (import "[export-payload]foo:foo/bar" "[stream-write-2]foo" (func (;53;) (type 2)))
-    (import "[export-payload]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;54;) (type 3)))
-    (import "[export-payload]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;55;) (type 3)))
-    (import "[export-payload]foo:foo/bar" "[stream-close-readable-2]foo" (func (;56;) (type 4)))
-    (import "[export-payload]foo:foo/bar" "[stream-close-writable-2]foo" (func (;57;) (type 5)))
-    (import "[export-payload]$root" "[future-new-0]foo" (func (;58;) (type 1)))
-    (import "[export-payload]$root" "[future-read-0]foo" (func (;59;) (type 0)))
-    (import "[export-payload]$root" "[future-write-0]foo" (func (;60;) (type 0)))
-    (import "[export-payload]$root" "[future-cancel-read-0]foo" (func (;61;) (type 3)))
-    (import "[export-payload]$root" "[future-cancel-write-0]foo" (func (;62;) (type 3)))
-    (import "[export-payload]$root" "[future-close-readable-0]foo" (func (;63;) (type 4)))
-    (import "[export-payload]$root" "[future-close-writable-0]foo" (func (;64;) (type 5)))
-    (import "[export-payload]foo:foo/bar" "[future-new-0]foo" (func (;65;) (type 1)))
-    (import "[export-payload]foo:foo/bar" "[future-read-0]foo" (func (;66;) (type 0)))
-    (import "[export-payload]foo:foo/bar" "[future-write-0]foo" (func (;67;) (type 0)))
-    (import "[export-payload]foo:foo/bar" "[future-cancel-read-0]foo" (func (;68;) (type 3)))
-    (import "[export-payload]foo:foo/bar" "[future-cancel-write-0]foo" (func (;69;) (type 3)))
-    (import "[export-payload]foo:foo/bar" "[future-close-readable-0]foo" (func (;70;) (type 4)))
-    (import "[export-payload]foo:foo/bar" "[future-close-writable-0]foo" (func (;71;) (type 5)))
-    (import "[export-payload]$root" "[future-new-1]foo" (func (;72;) (type 1)))
-    (import "[export-payload]$root" "[future-read-1]foo" (func (;73;) (type 0)))
-    (import "[export-payload]$root" "[future-write-1]foo" (func (;74;) (type 0)))
-    (import "[export-payload]$root" "[future-cancel-read-1]foo" (func (;75;) (type 3)))
-    (import "[export-payload]$root" "[future-cancel-write-1]foo" (func (;76;) (type 3)))
-    (import "[export-payload]$root" "[future-close-readable-1]foo" (func (;77;) (type 4)))
-    (import "[export-payload]$root" "[future-close-writable-1]foo" (func (;78;) (type 5)))
-    (import "[export-payload]foo:foo/bar" "[future-new-1]foo" (func (;79;) (type 1)))
-    (import "[export-payload]foo:foo/bar" "[future-read-1]foo" (func (;80;) (type 0)))
-    (import "[export-payload]foo:foo/bar" "[future-write-1]foo" (func (;81;) (type 0)))
-    (import "[export-payload]foo:foo/bar" "[future-cancel-read-1]foo" (func (;82;) (type 3)))
-    (import "[export-payload]foo:foo/bar" "[future-cancel-write-1]foo" (func (;83;) (type 3)))
-    (import "[export-payload]foo:foo/bar" "[future-close-readable-1]foo" (func (;84;) (type 4)))
-    (import "[export-payload]foo:foo/bar" "[future-close-writable-1]foo" (func (;85;) (type 5)))
+    (import "$root" "[stream-new-2]foo" (func (;2;) (type 1)))
+    (import "$root" "[stream-read-2]foo" (func (;3;) (type 2)))
+    (import "$root" "[stream-write-2]foo" (func (;4;) (type 2)))
+    (import "$root" "[stream-cancel-read-2]foo" (func (;5;) (type 3)))
+    (import "$root" "[stream-cancel-write-2]foo" (func (;6;) (type 3)))
+    (import "$root" "[stream-close-readable-2]foo" (func (;7;) (type 4)))
+    (import "$root" "[stream-close-writable-2]foo" (func (;8;) (type 5)))
+    (import "foo:foo/bar" "[stream-new-2]foo" (func (;9;) (type 1)))
+    (import "foo:foo/bar" "[stream-read-2]foo" (func (;10;) (type 2)))
+    (import "foo:foo/bar" "[stream-write-2]foo" (func (;11;) (type 2)))
+    (import "foo:foo/bar" "[stream-cancel-read-2]foo" (func (;12;) (type 3)))
+    (import "foo:foo/bar" "[stream-cancel-write-2]foo" (func (;13;) (type 3)))
+    (import "foo:foo/bar" "[stream-close-readable-2]foo" (func (;14;) (type 4)))
+    (import "foo:foo/bar" "[stream-close-writable-2]foo" (func (;15;) (type 5)))
+    (import "$root" "[future-new-0]foo" (func (;16;) (type 1)))
+    (import "$root" "[future-read-0]foo" (func (;17;) (type 0)))
+    (import "$root" "[future-write-0]foo" (func (;18;) (type 0)))
+    (import "$root" "[future-cancel-read-0]foo" (func (;19;) (type 3)))
+    (import "$root" "[future-cancel-write-0]foo" (func (;20;) (type 3)))
+    (import "$root" "[future-close-readable-0]foo" (func (;21;) (type 4)))
+    (import "$root" "[future-close-writable-0]foo" (func (;22;) (type 5)))
+    (import "foo:foo/bar" "[future-new-0]foo" (func (;23;) (type 1)))
+    (import "foo:foo/bar" "[future-read-0]foo" (func (;24;) (type 0)))
+    (import "foo:foo/bar" "[future-write-0]foo" (func (;25;) (type 0)))
+    (import "foo:foo/bar" "[future-cancel-read-0]foo" (func (;26;) (type 3)))
+    (import "foo:foo/bar" "[future-cancel-write-0]foo" (func (;27;) (type 3)))
+    (import "foo:foo/bar" "[future-close-readable-0]foo" (func (;28;) (type 4)))
+    (import "foo:foo/bar" "[future-close-writable-0]foo" (func (;29;) (type 5)))
+    (import "$root" "[future-new-1]foo" (func (;30;) (type 1)))
+    (import "$root" "[future-read-1]foo" (func (;31;) (type 0)))
+    (import "$root" "[future-write-1]foo" (func (;32;) (type 0)))
+    (import "$root" "[future-cancel-read-1]foo" (func (;33;) (type 3)))
+    (import "$root" "[future-cancel-write-1]foo" (func (;34;) (type 3)))
+    (import "$root" "[future-close-readable-1]foo" (func (;35;) (type 4)))
+    (import "$root" "[future-close-writable-1]foo" (func (;36;) (type 5)))
+    (import "foo:foo/bar" "[future-new-1]foo" (func (;37;) (type 1)))
+    (import "foo:foo/bar" "[future-read-1]foo" (func (;38;) (type 0)))
+    (import "foo:foo/bar" "[future-write-1]foo" (func (;39;) (type 0)))
+    (import "foo:foo/bar" "[future-cancel-read-1]foo" (func (;40;) (type 3)))
+    (import "foo:foo/bar" "[future-cancel-write-1]foo" (func (;41;) (type 3)))
+    (import "foo:foo/bar" "[future-close-readable-1]foo" (func (;42;) (type 4)))
+    (import "foo:foo/bar" "[future-close-writable-1]foo" (func (;43;) (type 5)))
+    (import "[export]$root" "[stream-new-2]foo" (func (;44;) (type 1)))
+    (import "[export]$root" "[stream-read-2]foo" (func (;45;) (type 2)))
+    (import "[export]$root" "[stream-write-2]foo" (func (;46;) (type 2)))
+    (import "[export]$root" "[stream-cancel-read-2]foo" (func (;47;) (type 3)))
+    (import "[export]$root" "[stream-cancel-write-2]foo" (func (;48;) (type 3)))
+    (import "[export]$root" "[stream-close-readable-2]foo" (func (;49;) (type 4)))
+    (import "[export]$root" "[stream-close-writable-2]foo" (func (;50;) (type 5)))
+    (import "[export]foo:foo/bar" "[stream-new-2]foo" (func (;51;) (type 1)))
+    (import "[export]foo:foo/bar" "[stream-read-2]foo" (func (;52;) (type 2)))
+    (import "[export]foo:foo/bar" "[stream-write-2]foo" (func (;53;) (type 2)))
+    (import "[export]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;54;) (type 3)))
+    (import "[export]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;55;) (type 3)))
+    (import "[export]foo:foo/bar" "[stream-close-readable-2]foo" (func (;56;) (type 4)))
+    (import "[export]foo:foo/bar" "[stream-close-writable-2]foo" (func (;57;) (type 5)))
+    (import "[export]$root" "[future-new-0]foo" (func (;58;) (type 1)))
+    (import "[export]$root" "[future-read-0]foo" (func (;59;) (type 0)))
+    (import "[export]$root" "[future-write-0]foo" (func (;60;) (type 0)))
+    (import "[export]$root" "[future-cancel-read-0]foo" (func (;61;) (type 3)))
+    (import "[export]$root" "[future-cancel-write-0]foo" (func (;62;) (type 3)))
+    (import "[export]$root" "[future-close-readable-0]foo" (func (;63;) (type 4)))
+    (import "[export]$root" "[future-close-writable-0]foo" (func (;64;) (type 5)))
+    (import "[export]foo:foo/bar" "[future-new-0]foo" (func (;65;) (type 1)))
+    (import "[export]foo:foo/bar" "[future-read-0]foo" (func (;66;) (type 0)))
+    (import "[export]foo:foo/bar" "[future-write-0]foo" (func (;67;) (type 0)))
+    (import "[export]foo:foo/bar" "[future-cancel-read-0]foo" (func (;68;) (type 3)))
+    (import "[export]foo:foo/bar" "[future-cancel-write-0]foo" (func (;69;) (type 3)))
+    (import "[export]foo:foo/bar" "[future-close-readable-0]foo" (func (;70;) (type 4)))
+    (import "[export]foo:foo/bar" "[future-close-writable-0]foo" (func (;71;) (type 5)))
+    (import "[export]$root" "[future-new-1]foo" (func (;72;) (type 1)))
+    (import "[export]$root" "[future-read-1]foo" (func (;73;) (type 0)))
+    (import "[export]$root" "[future-write-1]foo" (func (;74;) (type 0)))
+    (import "[export]$root" "[future-cancel-read-1]foo" (func (;75;) (type 3)))
+    (import "[export]$root" "[future-cancel-write-1]foo" (func (;76;) (type 3)))
+    (import "[export]$root" "[future-close-readable-1]foo" (func (;77;) (type 4)))
+    (import "[export]$root" "[future-close-writable-1]foo" (func (;78;) (type 5)))
+    (import "[export]foo:foo/bar" "[future-new-1]foo" (func (;79;) (type 1)))
+    (import "[export]foo:foo/bar" "[future-read-1]foo" (func (;80;) (type 0)))
+    (import "[export]foo:foo/bar" "[future-write-1]foo" (func (;81;) (type 0)))
+    (import "[export]foo:foo/bar" "[future-cancel-read-1]foo" (func (;82;) (type 3)))
+    (import "[export]foo:foo/bar" "[future-cancel-write-1]foo" (func (;83;) (type 3)))
+    (import "[export]foo:foo/bar" "[future-close-readable-1]foo" (func (;84;) (type 4)))
+    (import "[export]foo:foo/bar" "[future-close-writable-1]foo" (func (;85;) (type 5)))
     (memory (;0;) 1)
     (export "[async-stackful]foo" (func 86))
     (export "[async-stackful]foo:foo/bar#foo" (func 87))
@@ -133,31 +133,31 @@
     (type (;2;) (func (param i32 i32) (result i32)))
     (table (;0;) 26 26 funcref)
     (export "0" (func $"indirect-$root-[async]foo"))
-    (export "1" (func $"indirect-foo:foo/bar-[async]foo"))
-    (export "2" (func $"[import-payload]$root-[stream-read-2]foo"))
-    (export "3" (func $"[import-payload]$root-[stream-write-2]foo"))
-    (export "4" (func $"[import-payload]$root-[future-read-0]foo"))
-    (export "5" (func $"[import-payload]$root-[future-write-0]foo"))
-    (export "6" (func $"[import-payload]$root-[future-read-1]foo"))
-    (export "7" (func $"[import-payload]$root-[future-write-1]foo"))
-    (export "8" (func $"[import-payload]foo:foo/bar-[stream-read-2]foo"))
-    (export "9" (func $"[import-payload]foo:foo/bar-[stream-write-2]foo"))
-    (export "10" (func $"[import-payload]foo:foo/bar-[future-read-0]foo"))
-    (export "11" (func $"[import-payload]foo:foo/bar-[future-write-0]foo"))
-    (export "12" (func $"[import-payload]foo:foo/bar-[future-read-1]foo"))
-    (export "13" (func $"[import-payload]foo:foo/bar-[future-write-1]foo"))
-    (export "14" (func $"[export-payload]$root-[stream-read-2]foo"))
-    (export "15" (func $"[export-payload]$root-[stream-write-2]foo"))
-    (export "16" (func $"[export-payload]$root-[future-read-0]foo"))
-    (export "17" (func $"[export-payload]$root-[future-write-0]foo"))
-    (export "18" (func $"[export-payload]$root-[future-read-1]foo"))
-    (export "19" (func $"[export-payload]$root-[future-write-1]foo"))
-    (export "20" (func $"[export-payload]foo:foo/bar-[stream-read-2]foo"))
-    (export "21" (func $"[export-payload]foo:foo/bar-[stream-write-2]foo"))
-    (export "22" (func $"[export-payload]foo:foo/bar-[future-read-0]foo"))
-    (export "23" (func $"[export-payload]foo:foo/bar-[future-write-0]foo"))
-    (export "24" (func $"[export-payload]foo:foo/bar-[future-read-1]foo"))
-    (export "25" (func $"[export-payload]foo:foo/bar-[future-write-1]foo"))
+    (export "1" (func $"$root-[stream-read-2]foo"))
+    (export "2" (func $"$root-[stream-write-2]foo"))
+    (export "3" (func $"$root-[future-read-0]foo"))
+    (export "4" (func $"$root-[future-write-0]foo"))
+    (export "5" (func $"$root-[future-read-1]foo"))
+    (export "6" (func $"$root-[future-write-1]foo"))
+    (export "7" (func $"indirect-foo:foo/bar-[async]foo"))
+    (export "8" (func $"foo:foo/bar-[stream-read-2]foo"))
+    (export "9" (func $"foo:foo/bar-[stream-write-2]foo"))
+    (export "10" (func $"foo:foo/bar-[future-read-0]foo"))
+    (export "11" (func $"foo:foo/bar-[future-write-0]foo"))
+    (export "12" (func $"foo:foo/bar-[future-read-1]foo"))
+    (export "13" (func $"foo:foo/bar-[future-write-1]foo"))
+    (export "14" (func $"[export]$root-[stream-read-2]foo"))
+    (export "15" (func $"[export]$root-[stream-write-2]foo"))
+    (export "16" (func $"[export]$root-[future-read-0]foo"))
+    (export "17" (func $"[export]$root-[future-write-0]foo"))
+    (export "18" (func $"[export]$root-[future-read-1]foo"))
+    (export "19" (func $"[export]$root-[future-write-1]foo"))
+    (export "20" (func $"[export]foo:foo/bar-[stream-read-2]foo"))
+    (export "21" (func $"[export]foo:foo/bar-[stream-write-2]foo"))
+    (export "22" (func $"[export]foo:foo/bar-[future-read-0]foo"))
+    (export "23" (func $"[export]foo:foo/bar-[future-write-0]foo"))
+    (export "24" (func $"[export]foo:foo/bar-[future-read-1]foo"))
+    (export "25" (func $"[export]foo:foo/bar-[future-write-1]foo"))
     (export "$imports" (table 0))
     (func $"indirect-$root-[async]foo" (;0;) (type 0) (param i32 i32) (result i32)
       local.get 0
@@ -165,159 +165,159 @@
       i32.const 0
       call_indirect (type 0)
     )
-    (func $"indirect-foo:foo/bar-[async]foo" (;1;) (type 0) (param i32 i32) (result i32)
+    (func $"$root-[stream-read-2]foo" (;1;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
+      local.get 2
       i32.const 1
-      call_indirect (type 0)
+      call_indirect (type 1)
     )
-    (func $"[import-payload]$root-[stream-read-2]foo" (;2;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"$root-[stream-write-2]foo" (;2;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 2
       call_indirect (type 1)
     )
-    (func $"[import-payload]$root-[stream-write-2]foo" (;3;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"$root-[future-read-0]foo" (;3;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
-      local.get 2
       i32.const 3
-      call_indirect (type 1)
+      call_indirect (type 2)
     )
-    (func $"[import-payload]$root-[future-read-0]foo" (;4;) (type 2) (param i32 i32) (result i32)
+    (func $"$root-[future-write-0]foo" (;4;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 4
       call_indirect (type 2)
     )
-    (func $"[import-payload]$root-[future-write-0]foo" (;5;) (type 2) (param i32 i32) (result i32)
+    (func $"$root-[future-read-1]foo" (;5;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 5
       call_indirect (type 2)
     )
-    (func $"[import-payload]$root-[future-read-1]foo" (;6;) (type 2) (param i32 i32) (result i32)
+    (func $"$root-[future-write-1]foo" (;6;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 6
       call_indirect (type 2)
     )
-    (func $"[import-payload]$root-[future-write-1]foo" (;7;) (type 2) (param i32 i32) (result i32)
+    (func $"indirect-foo:foo/bar-[async]foo" (;7;) (type 0) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 7
-      call_indirect (type 2)
+      call_indirect (type 0)
     )
-    (func $"[import-payload]foo:foo/bar-[stream-read-2]foo" (;8;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"foo:foo/bar-[stream-read-2]foo" (;8;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 8
       call_indirect (type 1)
     )
-    (func $"[import-payload]foo:foo/bar-[stream-write-2]foo" (;9;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"foo:foo/bar-[stream-write-2]foo" (;9;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 9
       call_indirect (type 1)
     )
-    (func $"[import-payload]foo:foo/bar-[future-read-0]foo" (;10;) (type 2) (param i32 i32) (result i32)
+    (func $"foo:foo/bar-[future-read-0]foo" (;10;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 10
       call_indirect (type 2)
     )
-    (func $"[import-payload]foo:foo/bar-[future-write-0]foo" (;11;) (type 2) (param i32 i32) (result i32)
+    (func $"foo:foo/bar-[future-write-0]foo" (;11;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 11
       call_indirect (type 2)
     )
-    (func $"[import-payload]foo:foo/bar-[future-read-1]foo" (;12;) (type 2) (param i32 i32) (result i32)
+    (func $"foo:foo/bar-[future-read-1]foo" (;12;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 12
       call_indirect (type 2)
     )
-    (func $"[import-payload]foo:foo/bar-[future-write-1]foo" (;13;) (type 2) (param i32 i32) (result i32)
+    (func $"foo:foo/bar-[future-write-1]foo" (;13;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 13
       call_indirect (type 2)
     )
-    (func $"[export-payload]$root-[stream-read-2]foo" (;14;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"[export]$root-[stream-read-2]foo" (;14;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 14
       call_indirect (type 1)
     )
-    (func $"[export-payload]$root-[stream-write-2]foo" (;15;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"[export]$root-[stream-write-2]foo" (;15;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 15
       call_indirect (type 1)
     )
-    (func $"[export-payload]$root-[future-read-0]foo" (;16;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]$root-[future-read-0]foo" (;16;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 16
       call_indirect (type 2)
     )
-    (func $"[export-payload]$root-[future-write-0]foo" (;17;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]$root-[future-write-0]foo" (;17;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 17
       call_indirect (type 2)
     )
-    (func $"[export-payload]$root-[future-read-1]foo" (;18;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]$root-[future-read-1]foo" (;18;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 18
       call_indirect (type 2)
     )
-    (func $"[export-payload]$root-[future-write-1]foo" (;19;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]$root-[future-write-1]foo" (;19;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 19
       call_indirect (type 2)
     )
-    (func $"[export-payload]foo:foo/bar-[stream-read-2]foo" (;20;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"[export]foo:foo/bar-[stream-read-2]foo" (;20;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 20
       call_indirect (type 1)
     )
-    (func $"[export-payload]foo:foo/bar-[stream-write-2]foo" (;21;) (type 1) (param i32 i32 i32) (result i32)
+    (func $"[export]foo:foo/bar-[stream-write-2]foo" (;21;) (type 1) (param i32 i32 i32) (result i32)
       local.get 0
       local.get 1
       local.get 2
       i32.const 21
       call_indirect (type 1)
     )
-    (func $"[export-payload]foo:foo/bar-[future-read-0]foo" (;22;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]foo:foo/bar-[future-read-0]foo" (;22;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 22
       call_indirect (type 2)
     )
-    (func $"[export-payload]foo:foo/bar-[future-write-0]foo" (;23;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]foo:foo/bar-[future-write-0]foo" (;23;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 23
       call_indirect (type 2)
     )
-    (func $"[export-payload]foo:foo/bar-[future-read-1]foo" (;24;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]foo:foo/bar-[future-read-1]foo" (;24;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 24
       call_indirect (type 2)
     )
-    (func $"[export-payload]foo:foo/bar-[future-write-1]foo" (;25;) (type 2) (param i32 i32) (result i32)
+    (func $"[export]foo:foo/bar-[future-write-1]foo" (;25;) (type 2) (param i32 i32) (result i32)
       local.get 0
       local.get 1
       i32.const 25
@@ -332,13 +332,13 @@
     (type (;1;) (func (param i32 i32 i32) (result i32)))
     (type (;2;) (func (param i32 i32) (result i32)))
     (import "" "0" (func (;0;) (type 0)))
-    (import "" "1" (func (;1;) (type 0)))
+    (import "" "1" (func (;1;) (type 1)))
     (import "" "2" (func (;2;) (type 1)))
-    (import "" "3" (func (;3;) (type 1)))
+    (import "" "3" (func (;3;) (type 2)))
     (import "" "4" (func (;4;) (type 2)))
     (import "" "5" (func (;5;) (type 2)))
     (import "" "6" (func (;6;) (type 2)))
-    (import "" "7" (func (;7;) (type 2)))
+    (import "" "7" (func (;7;) (type 0)))
     (import "" "8" (func (;8;) (type 1)))
     (import "" "9" (func (;9;) (type 1)))
     (import "" "10" (func (;10;) (type 2)))
@@ -365,57 +365,52 @@
   )
   (core instance (;0;) (instantiate 1))
   (alias core export 0 "0" (core func (;0;)))
-  (core instance (;1;)
-    (export "[async]foo" (func 0))
-  )
-  (alias core export 0 "1" (core func (;1;)))
-  (core instance (;2;)
-    (export "[async]foo" (func 1))
-  )
-  (core func (;2;) (canon stream.new 3))
+  (core func (;1;) (canon stream.new 3))
+  (alias core export 0 "1" (core func (;2;)))
   (alias core export 0 "2" (core func (;3;)))
-  (alias core export 0 "3" (core func (;4;)))
-  (core func (;5;) (canon stream.cancel-read 3))
-  (core func (;6;) (canon stream.cancel-write 3))
-  (core func (;7;) (canon stream.close-readable 3))
-  (core func (;8;) (canon stream.close-writable 3))
-  (core func (;9;) (canon future.new 1))
+  (core func (;4;) (canon stream.cancel-read 3))
+  (core func (;5;) (canon stream.cancel-write 3))
+  (core func (;6;) (canon stream.close-readable 3))
+  (core func (;7;) (canon stream.close-writable 3))
+  (core func (;8;) (canon future.new 1))
+  (alias core export 0 "3" (core func (;9;)))
   (alias core export 0 "4" (core func (;10;)))
-  (alias core export 0 "5" (core func (;11;)))
-  (core func (;12;) (canon future.cancel-read 1))
-  (core func (;13;) (canon future.cancel-write 1))
-  (core func (;14;) (canon future.close-readable 1))
-  (core func (;15;) (canon future.close-writable 1))
-  (core func (;16;) (canon future.new 2))
+  (core func (;11;) (canon future.cancel-read 1))
+  (core func (;12;) (canon future.cancel-write 1))
+  (core func (;13;) (canon future.close-readable 1))
+  (core func (;14;) (canon future.close-writable 1))
+  (core func (;15;) (canon future.new 2))
+  (alias core export 0 "5" (core func (;16;)))
   (alias core export 0 "6" (core func (;17;)))
-  (alias core export 0 "7" (core func (;18;)))
-  (core func (;19;) (canon future.cancel-read 2))
-  (core func (;20;) (canon future.cancel-write 2))
-  (core func (;21;) (canon future.close-readable 2))
-  (core func (;22;) (canon future.close-writable 2))
-  (core instance (;3;)
-    (export "[stream-new-2]foo" (func 2))
-    (export "[stream-read-2]foo" (func 3))
-    (export "[stream-write-2]foo" (func 4))
-    (export "[stream-cancel-read-2]foo" (func 5))
-    (export "[stream-cancel-write-2]foo" (func 6))
-    (export "[stream-close-readable-2]foo" (func 7))
-    (export "[stream-close-writable-2]foo" (func 8))
-    (export "[future-new-0]foo" (func 9))
-    (export "[future-read-0]foo" (func 10))
-    (export "[future-write-0]foo" (func 11))
-    (export "[future-cancel-read-0]foo" (func 12))
-    (export "[future-cancel-write-0]foo" (func 13))
-    (export "[future-close-readable-0]foo" (func 14))
-    (export "[future-close-writable-0]foo" (func 15))
-    (export "[future-new-1]foo" (func 16))
-    (export "[future-read-1]foo" (func 17))
-    (export "[future-write-1]foo" (func 18))
-    (export "[future-cancel-read-1]foo" (func 19))
-    (export "[future-cancel-write-1]foo" (func 20))
-    (export "[future-close-readable-1]foo" (func 21))
-    (export "[future-close-writable-1]foo" (func 22))
+  (core func (;18;) (canon future.cancel-read 2))
+  (core func (;19;) (canon future.cancel-write 2))
+  (core func (;20;) (canon future.close-readable 2))
+  (core func (;21;) (canon future.close-writable 2))
+  (core instance (;1;)
+    (export "[async]foo" (func 0))
+    (export "[stream-new-2]foo" (func 1))
+    (export "[stream-read-2]foo" (func 2))
+    (export "[stream-write-2]foo" (func 3))
+    (export "[stream-cancel-read-2]foo" (func 4))
+    (export "[stream-cancel-write-2]foo" (func 5))
+    (export "[stream-close-readable-2]foo" (func 6))
+    (export "[stream-close-writable-2]foo" (func 7))
+    (export "[future-new-0]foo" (func 8))
+    (export "[future-read-0]foo" (func 9))
+    (export "[future-write-0]foo" (func 10))
+    (export "[future-cancel-read-0]foo" (func 11))
+    (export "[future-cancel-write-0]foo" (func 12))
+    (export "[future-close-readable-0]foo" (func 13))
+    (export "[future-close-writable-0]foo" (func 14))
+    (export "[future-new-1]foo" (func 15))
+    (export "[future-read-1]foo" (func 16))
+    (export "[future-write-1]foo" (func 17))
+    (export "[future-cancel-read-1]foo" (func 18))
+    (export "[future-cancel-write-1]foo" (func 19))
+    (export "[future-close-readable-1]foo" (func 20))
+    (export "[future-close-writable-1]foo" (func 21))
   )
+  (alias core export 0 "7" (core func (;22;)))
   (type (;5;) (stream string))
   (core func (;23;) (canon stream.new 5))
   (alias core export 0 "8" (core func (;24;)))
@@ -440,7 +435,8 @@
   (core func (;41;) (canon future.cancel-write 7))
   (core func (;42;) (canon future.close-readable 7))
   (core func (;43;) (canon future.close-writable 7))
-  (core instance (;4;)
+  (core instance (;2;)
+    (export "[async]foo" (func 22))
     (export "[stream-new-2]foo" (func 23))
     (export "[stream-read-2]foo" (func 24))
     (export "[stream-write-2]foo" (func 25))
@@ -487,7 +483,7 @@
   (core func (;62;) (canon future.cancel-write 10))
   (core func (;63;) (canon future.close-readable 10))
   (core func (;64;) (canon future.close-writable 10))
-  (core instance (;5;)
+  (core instance (;3;)
     (export "[stream-new-2]foo" (func 44))
     (export "[stream-read-2]foo" (func 45))
     (export "[stream-write-2]foo" (func 46))
@@ -534,7 +530,7 @@
   (core func (;83;) (canon future.cancel-write 13))
   (core func (;84;) (canon future.close-readable 13))
   (core func (;85;) (canon future.close-writable 13))
-  (core instance (;6;)
+  (core instance (;4;)
     (export "[stream-new-2]foo" (func 65))
     (export "[stream-read-2]foo" (func 66))
     (export "[stream-write-2]foo" (func 67))
@@ -557,27 +553,25 @@
     (export "[future-close-readable-1]foo" (func 84))
     (export "[future-close-writable-1]foo" (func 85))
   )
-  (core instance (;7;) (instantiate 0
+  (core instance (;5;) (instantiate 0
       (with "$root" (instance 1))
       (with "foo:foo/bar" (instance 2))
-      (with "[import-payload]$root" (instance 3))
-      (with "[import-payload]foo:foo/bar" (instance 4))
-      (with "[export-payload]$root" (instance 5))
-      (with "[export-payload]foo:foo/bar" (instance 6))
+      (with "[export]$root" (instance 3))
+      (with "[export]foo:foo/bar" (instance 4))
     )
   )
-  (alias core export 7 "memory" (core memory (;0;)))
+  (alias core export 5 "memory" (core memory (;0;)))
   (alias core export 0 "$imports" (core table (;0;)))
-  (alias core export 7 "cabi_realloc" (core func (;86;)))
+  (alias core export 5 "cabi_realloc" (core func (;86;)))
   (core func (;87;) (canon lower (func 0) (memory 0) async))
+  (core func (;88;) (canon stream.read 3 (memory 0) (realloc 86) string-encoding=utf8))
+  (core func (;89;) (canon stream.write 3 (memory 0) string-encoding=utf8))
+  (core func (;90;) (canon future.read 1 (memory 0)))
+  (core func (;91;) (canon future.write 1 (memory 0)))
+  (core func (;92;) (canon future.read 2 (memory 0)))
+  (core func (;93;) (canon future.write 2 (memory 0)))
   (alias export 0 "foo" (func (;1;)))
-  (core func (;88;) (canon lower (func 1) (memory 0) async))
-  (core func (;89;) (canon stream.read 3 (memory 0) (realloc 86) string-encoding=utf8))
-  (core func (;90;) (canon stream.write 3 (memory 0) string-encoding=utf8))
-  (core func (;91;) (canon future.read 1 (memory 0)))
-  (core func (;92;) (canon future.write 1 (memory 0)))
-  (core func (;93;) (canon future.read 2 (memory 0)))
-  (core func (;94;) (canon future.write 2 (memory 0)))
+  (core func (;94;) (canon lower (func 1) (memory 0) async))
   (core func (;95;) (canon stream.read 5 (memory 0) (realloc 86) string-encoding=utf8))
   (core func (;96;) (canon stream.write 5 (memory 0) string-encoding=utf8))
   (core func (;97;) (canon future.read 6 (memory 0)))
@@ -596,7 +590,7 @@
   (core func (;110;) (canon future.write 12 (memory 0)))
   (core func (;111;) (canon future.read 13 (memory 0)))
   (core func (;112;) (canon future.write 13 (memory 0)))
-  (core instance (;8;)
+  (core instance (;6;)
     (export "$imports" (table 0))
     (export "0" (func 87))
     (export "1" (func 88))
@@ -625,15 +619,15 @@
     (export "24" (func 111))
     (export "25" (func 112))
   )
-  (core instance (;9;) (instantiate 2
-      (with "" (instance 8))
+  (core instance (;7;) (instantiate 2
+      (with "" (instance 6))
     )
   )
-  (alias core export 7 "[async-stackful]foo" (core func (;113;)))
+  (alias core export 5 "[async-stackful]foo" (core func (;113;)))
   (func (;2;) (type 4) (canon lift (core func 113) async))
   (export (;3;) "foo" (func 2))
   (type (;14;) (func (param "x" 13) (param "y" u32) (result 11)))
-  (alias core export 7 "[async-stackful]foo:foo/bar#foo" (core func (;114;)))
+  (alias core export 5 "[async-stackful]foo:foo/bar#foo" (core func (;114;)))
   (func (;4;) (type 14) (canon lift (core func 114) async))
   (component (;0;)
     (type (;0;) (future u32))
diff --git a/crates/wit-component/tests/components/async-streams-and-futures/module.wat b/crates/wit-component/tests/components/async-streams-and-futures/module.wat
index a62c67a0..934fa4bb 100644
--- a/crates/wit-component/tests/components/async-streams-and-futures/module.wat
+++ b/crates/wit-component/tests/components/async-streams-and-futures/module.wat
@@ -1,90 +1,90 @@
 (module
   (func (import "$root" "[async]foo") (param i32 i32) (result i32))
   (func (import "foo:foo/bar" "[async]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[stream-new-2]foo") (result i32))
-  (func (import "[import-payload]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[stream-cancel-read-2]foo") (param i32) (result i32))
-  (func (import "[import-payload]$root" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "[import-payload]$root" "[stream-close-readable-2]foo") (param i32))
-  (func (import "[import-payload]$root" "[stream-close-writable-2]foo") (param i32 i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-new-2]foo") (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-close-readable-2]foo") (param i32))
-  (func (import "[import-payload]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32))
-  (func (import "[import-payload]$root" "[future-new-0]foo") (result i32))
-  (func (import "[import-payload]$root" "[future-read-0]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[future-write-0]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[future-cancel-read-0]foo") (param i32) (result i32))
-  (func (import "[import-payload]$root" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "[import-payload]$root" "[future-close-readable-0]foo") (param i32))
-  (func (import "[import-payload]$root" "[future-close-writable-0]foo") (param i32 i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-new-0]foo") (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-close-readable-0]foo") (param i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32))
-  (func (import "[import-payload]$root" "[future-new-1]foo") (result i32))
-  (func (import "[import-payload]$root" "[future-read-1]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[future-write-1]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]$root" "[future-cancel-read-1]foo") (param i32) (result i32))
-  (func (import "[import-payload]$root" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "[import-payload]$root" "[future-close-readable-1]foo") (param i32))
-  (func (import "[import-payload]$root" "[future-close-writable-1]foo") (param i32 i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-new-1]foo") (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-close-readable-1]foo") (param i32))
-  (func (import "[import-payload]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32))
-  (func (import "[export-payload]$root" "[stream-new-2]foo") (result i32))
-  (func (import "[export-payload]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[export-payload]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[export-payload]$root" "[stream-cancel-read-2]foo") (param i32) (result i32))
-  (func (import "[export-payload]$root" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "[export-payload]$root" "[stream-close-readable-2]foo") (param i32))
-  (func (import "[export-payload]$root" "[stream-close-writable-2]foo") (param i32 i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-new-2]foo") (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-close-readable-2]foo") (param i32))
-  (func (import "[export-payload]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32))
-  (func (import "[export-payload]$root" "[future-new-0]foo") (result i32))
-  (func (import "[export-payload]$root" "[future-read-0]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]$root" "[future-write-0]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]$root" "[future-cancel-read-0]foo") (param i32) (result i32))
-  (func (import "[export-payload]$root" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "[export-payload]$root" "[future-close-readable-0]foo") (param i32))
-  (func (import "[export-payload]$root" "[future-close-writable-0]foo") (param i32 i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-new-0]foo") (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-close-readable-0]foo") (param i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32))
-  (func (import "[export-payload]$root" "[future-new-1]foo") (result i32))
-  (func (import "[export-payload]$root" "[future-read-1]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]$root" "[future-write-1]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]$root" "[future-cancel-read-1]foo") (param i32) (result i32))
-  (func (import "[export-payload]$root" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "[export-payload]$root" "[future-close-readable-1]foo") (param i32))
-  (func (import "[export-payload]$root" "[future-close-writable-1]foo") (param i32 i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-new-1]foo") (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-close-readable-1]foo") (param i32))
-  (func (import "[export-payload]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32))
+  (func (import "$root" "[stream-new-2]foo") (result i32))
+  (func (import "$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "$root" "[stream-cancel-read-2]foo") (param i32) (result i32))
+  (func (import "$root" "[stream-cancel-write-2]foo") (param i32) (result i32))
+  (func (import "$root" "[stream-close-readable-2]foo") (param i32))
+  (func (import "$root" "[stream-close-writable-2]foo") (param i32 i32))
+  (func (import "foo:foo/bar" "[stream-new-2]foo") (result i32))
+  (func (import "foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32))
+  (func (import "foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32))
+  (func (import "foo:foo/bar" "[stream-close-readable-2]foo") (param i32))
+  (func (import "foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32))
+  (func (import "$root" "[future-new-0]foo") (result i32))
+  (func (import "$root" "[future-read-0]foo") (param i32 i32) (result i32))
+  (func (import "$root" "[future-write-0]foo") (param i32 i32) (result i32))
+  (func (import "$root" "[future-cancel-read-0]foo") (param i32) (result i32))
+  (func (import "$root" "[future-cancel-write-0]foo") (param i32) (result i32))
+  (func (import "$root" "[future-close-readable-0]foo") (param i32))
+  (func (import "$root" "[future-close-writable-0]foo") (param i32 i32))
+  (func (import "foo:foo/bar" "[future-new-0]foo") (result i32))
+  (func (import "foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32))
+  (func (import "foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32))
+  (func (import "foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32))
+  (func (import "foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32))
+  (func (import "foo:foo/bar" "[future-close-readable-0]foo") (param i32))
+  (func (import "foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32))
+  (func (import "$root" "[future-new-1]foo") (result i32))
+  (func (import "$root" "[future-read-1]foo") (param i32 i32) (result i32))
+  (func (import "$root" "[future-write-1]foo") (param i32 i32) (result i32))
+  (func (import "$root" "[future-cancel-read-1]foo") (param i32) (result i32))
+  (func (import "$root" "[future-cancel-write-1]foo") (param i32) (result i32))
+  (func (import "$root" "[future-close-readable-1]foo") (param i32))
+  (func (import "$root" "[future-close-writable-1]foo") (param i32 i32))
+  (func (import "foo:foo/bar" "[future-new-1]foo") (result i32))
+  (func (import "foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32))
+  (func (import "foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32))
+  (func (import "foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32))
+  (func (import "foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32))
+  (func (import "foo:foo/bar" "[future-close-readable-1]foo") (param i32))
+  (func (import "foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32))
+  (func (import "[export]$root" "[stream-new-2]foo") (result i32))
+  (func (import "[export]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "[export]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "[export]$root" "[stream-cancel-read-2]foo") (param i32) (result i32))
+  (func (import "[export]$root" "[stream-cancel-write-2]foo") (param i32) (result i32))
+  (func (import "[export]$root" "[stream-close-readable-2]foo") (param i32))
+  (func (import "[export]$root" "[stream-close-writable-2]foo") (param i32 i32))
+  (func (import "[export]foo:foo/bar" "[stream-new-2]foo") (result i32))
+  (func (import "[export]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[stream-close-readable-2]foo") (param i32))
+  (func (import "[export]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32))
+  (func (import "[export]$root" "[future-new-0]foo") (result i32))
+  (func (import "[export]$root" "[future-read-0]foo") (param i32 i32) (result i32))
+  (func (import "[export]$root" "[future-write-0]foo") (param i32 i32) (result i32))
+  (func (import "[export]$root" "[future-cancel-read-0]foo") (param i32) (result i32))
+  (func (import "[export]$root" "[future-cancel-write-0]foo") (param i32) (result i32))
+  (func (import "[export]$root" "[future-close-readable-0]foo") (param i32))
+  (func (import "[export]$root" "[future-close-writable-0]foo") (param i32 i32))
+  (func (import "[export]foo:foo/bar" "[future-new-0]foo") (result i32))
+  (func (import "[export]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-close-readable-0]foo") (param i32))
+  (func (import "[export]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32))
+  (func (import "[export]$root" "[future-new-1]foo") (result i32))
+  (func (import "[export]$root" "[future-read-1]foo") (param i32 i32) (result i32))
+  (func (import "[export]$root" "[future-write-1]foo") (param i32 i32) (result i32))
+  (func (import "[export]$root" "[future-cancel-read-1]foo") (param i32) (result i32))
+  (func (import "[export]$root" "[future-cancel-write-1]foo") (param i32) (result i32))
+  (func (import "[export]$root" "[future-close-readable-1]foo") (param i32))
+  (func (import "[export]$root" "[future-close-writable-1]foo") (param i32 i32))
+  (func (import "[export]foo:foo/bar" "[future-new-1]foo") (result i32))
+  (func (import "[export]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32))
+  (func (import "[export]foo:foo/bar" "[future-close-readable-1]foo") (param i32))
+  (func (import "[export]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32))
   (func (export "[async-stackful]foo") (param i32 i32) unreachable)
   (func (export "[async-stackful]foo:foo/bar#foo") (param i32 i32) unreachable)
   (memory (export "memory") 1)