Repository: bytecodealliance/wasmtime
Pull request #8965 (2024-07-16 20:48:31)

Update wasm-tools and wit-bindgen crates
This keeps things updated and pulls in some new features from wasm-tools:

* Multiple returns in the component model are now gated by default. This is reflected in a new `Config` option and CLI flag. The hope is to remove this feature is no one ends up needing it.

* Support for more `shared` things were added but the feature is always disabled so internal handlers just panic.

Tests were updated to not use multiple returns where appropriate, except for one test which is specifically testing for multiple returns and how it's reflected into the Rust type system.

<!--
Please make sure you include the following information:

- If this work has been discussed elsewhere, please include a link to that
  conversation. If it was discussed in an issue, just mention "issue #...".

- Explain why this change is needed. If the details are in an issue already,
  this can be brief.

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->



Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 516122c26..cd4d20c15 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3235,9 +3235,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "wasm-encoder"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "501940df4418b8929eb6d52f1aade1fdd15a5b86c92453cb696e3c906bd3fc33"
+checksum = "ff694f02a8d7a50b6922b197ae03883fbf18cdb2ae9fbee7b6148456f5f44041"
 dependencies = [
  "leb128",
  "wasmparser",
@@ -3245,9 +3245,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-metadata"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a1849fac257fd76c43268555e73d74848c8dff23975c238c2cbad61cffe5045"
+checksum = "865c5bff5f7a3781b5f92ea4cfa99bb38267da097441cdb09080de1568ef3075"
 dependencies = [
  "anyhow",
  "indexmap 2.2.6",
@@ -3261,9 +3261,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-mutate"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff58202fe6f3750ba930d160a2451087973d902e09a2632b9a78ab7c86150a59"
+checksum = "bf9fb8fb035aaada5f46c4eac0fb93a493143708815f28a0a008e3c92074f270"
 dependencies = [
  "egg",
  "log",
@@ -3275,9 +3275,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-smith"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8185faf41a5630ec7cf301fa1f63bb757f4c267a057f8b6b56bde0cba1144c1"
+checksum = "ffe5856b6e06e8d37dad11167111e49339a5b017ab1399f7cb708fcb4c4550d0"
 dependencies = [
  "anyhow",
  "arbitrary",
@@ -3329,9 +3329,9 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d28bc49ba1e5c5b61ffa7a2eace10820443c4b7d1c0b144109261d14570fdf8"
+checksum = "5309c1090e3e84dad0d382f42064e9933fdaedb87e468cc239f0eabea73ddcb6"
 dependencies = [
  "ahash",
  "bitflags 2.4.1",
@@ -3352,9 +3352,9 @@ dependencies = [
 
 [[package]]
 name = "wasmprinter"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfac65326cc561112af88c3028f6dfdb140acff67ede33a8e86be2dc6b8956f7"
+checksum = "58d4f2b3f7bd2ba10f99e03f885ff90d5db3455e163bccecebbbf60406bd8980"
 dependencies = [
  "anyhow",
  "termcolor",
@@ -3559,7 +3559,7 @@ dependencies = [
  "wasmtime-wasi-nn",
  "wasmtime-wasi-threads",
  "wasmtime-wast",
- "wast 212.0.0",
+ "wast 214.0.0",
  "wat",
  "windows-sys 0.52.0",
  "wit-component",
@@ -3904,7 +3904,7 @@ dependencies = [
  "anyhow",
  "log",
  "wasmtime",
- "wast 212.0.0",
+ "wast 214.0.0",
 ]
 
 [[package]]
@@ -3947,9 +3947,9 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "212.0.0"
+version = "214.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4606a05fb0aae5d11dd7d8280a640d88a63ee019360ba9be552da3d294b8d1f5"
+checksum = "694bcdb24c49c8709bd8713768b71301a11e823923eee355d530f1d8d0a7f8e9"
 dependencies = [
  "bumpalo",
  "leb128",
@@ -3960,11 +3960,11 @@ dependencies = [
 
 [[package]]
 name = "wat"
-version = "1.212.0"
+version = "1.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c74ca7f93f11a5d6eed8499f2a8daaad6e225cab0151bc25a091fff3b987532f"
+checksum = "347249eb56773fa728df2656cfe3a8c19437ded61a922a0b5e0839d9790e278e"
 dependencies = [
- "wast 212.0.0",
+ "wast 214.0.0",
 ]
 
 [[package]]
@@ -4271,9 +4271,9 @@ dependencies = [
 
 [[package]]
 name = "wit-bindgen"
-version = "0.27.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fabce76bbb8938536c437da0c3e1d4dda9065453f72a68f797c0cb3d67356a28"
+checksum = "89178260ed223de8a5a81f9cff961481dfbbd55b25c17e4dd0b4c8e4b8ae646d"
 dependencies = [
  "wit-bindgen-rt",
  "wit-bindgen-rust-macro",
@@ -4281,9 +4281,9 @@ dependencies = [
 
 [[package]]
 name = "wit-bindgen-core"
-version = "0.27.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b43fbdd3497c471bbfb6973b1fb9ffe6949f158248cb43171d6f1cf3de7eaa3"
+checksum = "5e3fd9b11c16b9888c1bd159130b1b3487da913c45dbd34d408bfdf81f8a865a"
 dependencies = [
  "anyhow",
  "heck 0.5.0",
@@ -4292,18 +4292,18 @@ dependencies = [
 
 [[package]]
 name = "wit-bindgen-rt"
-version = "0.27.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75956ff0a04a87ca0526b07199ce3b9baee899f2e4723b5b63aa296ab172ec52"
+checksum = "d7a37bd9274cb2d4754b915d624447ec0dce9105d174361841c0826efc79ceb9"
 dependencies = [
  "bitflags 2.4.1",
 ]
 
 [[package]]
 name = "wit-bindgen-rust"
-version = "0.27.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf509c4ef97b18ec0218741c8318706ac30ff16bc1731f990319a42bbbcfe8e3"
+checksum = "0f195cd3774ff22f9bbd582a4ab97667c0a47d36ed8ed0c9ed357afe811b564b"
 dependencies = [
  "anyhow",
  "heck 0.5.0",
@@ -4317,9 +4317,9 @@ dependencies = [
 
 [[package]]
 name = "wit-bindgen-rust-macro"
-version = "0.27.0"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d6f2e025e38395d71fc1bf064e581b2ad275ce322d6f8d87ddc5e76a7b8c42"
+checksum = "683e47441b5d0a82fc4304619dcc0672bc84ef47de2c85cd493c37cb29de062f"
 dependencies = [
  "anyhow",
  "prettyplease",
@@ -4332,9 +4332,9 @@ dependencies = [
 
 [[package]]
 name = "wit-component"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ed5b0f9fc3d6424787d2a49e1142bf954ae4f26ee891992c144f0cfd68c4b7f"
+checksum = "fd9fd46f0e783bf80f1ab7291f9d442fa5553ff0e96cdb71964bd8859b734b55"
 dependencies = [
  "anyhow",
  "bitflags 2.4.1",
@@ -4351,9 +4351,9 @@ dependencies = [
 
 [[package]]
 name = "wit-parser"
-version = "0.212.0"
+version = "0.214.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ceeb0424aa8679f3fcf2d6e3cfa381f3d6fa6179976a2c05a6249dd2bb426716"
+checksum = "681d526d6ea42e28f9afe9eae2b50e0b0a627aef8822c75eb04078db84d03e57"
 dependencies = [
  "anyhow",
  "id-arena",
diff --git a/Cargo.toml b/Cargo.toml
index 3043a9320..5292e73cc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -249,19 +249,19 @@ io-lifetimes = { version = "2.0.3", default-features = false }
 io-extras = "0.18.1"
 rustix = "0.38.31"
 # wit-bindgen:
-wit-bindgen = { version = "0.27.0", default-features = false }
-wit-bindgen-rust-macro = { version = "0.27.0", default-features = false }
+wit-bindgen = { version = "0.28.0", default-features = false }
+wit-bindgen-rust-macro = { version = "0.28.0", default-features = false }
 
 # wasm-tools family:
-wasmparser = { version = "0.212.0", default-features = false }
-wat = "1.212.0"
-wast = "212.0.0"
-wasmprinter = "0.212.0"
-wasm-encoder = "0.212.0"
-wasm-smith = "0.212.0"
-wasm-mutate = "0.212.0"
-wit-parser = "0.212.0"
-wit-component = "0.212.0"
+wasmparser = { version = "0.214.0", default-features = false }
+wat = "1.214.0"
+wast = "214.0.0"
+wasmprinter = "0.214.0"
+wasm-encoder = "0.214.0"
+wasm-smith = "0.214.0"
+wasm-mutate = "0.214.0"
+wit-parser = "0.214.0"
+wit-component = "0.214.0"
 
 # Non-Bytecode Alliance maintained dependencies:
 # --------------------------
diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs
index b9308510b..044436aad 100644
--- a/cranelift/wasm/src/code_translator.rs
+++ b/cranelift/wasm/src/code_translator.rs
@@ -2551,7 +2551,34 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
         | Operator::GlobalAtomicRmwXor { .. }
         | Operator::GlobalAtomicRmwAnd { .. }
         | Operator::GlobalAtomicRmwXchg { .. }
-        | Operator::GlobalAtomicRmwCmpxchg { .. } => {
+        | Operator::GlobalAtomicRmwCmpxchg { .. }
+        | Operator::TableAtomicGet { .. }
+        | Operator::TableAtomicSet { .. }
+        | Operator::TableAtomicRmwXchg { .. }
+        | Operator::TableAtomicRmwCmpxchg { .. }
+        | Operator::StructAtomicGet { .. }
+        | Operator::StructAtomicGetS { .. }
+        | Operator::StructAtomicGetU { .. }
+        | Operator::StructAtomicSet { .. }
+        | Operator::StructAtomicRmwAdd { .. }
+        | Operator::StructAtomicRmwSub { .. }
+        | Operator::StructAtomicRmwOr { .. }
+        | Operator::StructAtomicRmwXor { .. }
+        | Operator::StructAtomicRmwAnd { .. }
+        | Operator::StructAtomicRmwXchg { .. }
+        | Operator::StructAtomicRmwCmpxchg { .. }
+        | Operator::ArrayAtomicGet { .. }
+        | Operator::ArrayAtomicGetS { .. }
+        | Operator::ArrayAtomicGetU { .. }
+        | Operator::ArrayAtomicSet { .. }
+        | Operator::ArrayAtomicRmwAdd { .. }
+        | Operator::ArrayAtomicRmwSub { .. }
+        | Operator::ArrayAtomicRmwOr { .. }
+        | Operator::ArrayAtomicRmwXor { .. }
+        | Operator::ArrayAtomicRmwAnd { .. }
+        | Operator::ArrayAtomicRmwXchg { .. }
+        | Operator::ArrayAtomicRmwCmpxchg { .. }
+        | Operator::RefI31Shared { .. } => {
             unimplemented!("shared-everything-threads not yet implemented")
         }
     };
diff --git a/crates/cli-flags/src/lib.rs b/crates/cli-flags/src/lib.rs
index 33249451c..d60bd2d26 100644
--- a/crates/cli-flags/src/lib.rs
+++ b/crates/cli-flags/src/lib.rs
@@ -256,6 +256,8 @@ wasmtime_option_group! {
         pub component_model: Option<bool>,
         /// Configure support for 33+ flags in the component model.
         pub component_model_more_flags: Option<bool>,
+        /// Component model support for more than one return value.
+        pub component_model_multiple_returns: Option<bool>,
         /// Configure support for the function-references proposal.
         pub function_references: Option<bool>,
         /// Configure support for the GC proposal.
@@ -682,6 +684,7 @@ impl CommonOptions {
         handle_conditionally_compiled! {
             ("component-model", component_model, wasm_component_model)
             ("component-model", component_model_more_flags, wasm_component_model_more_flags)
+            ("component-model", component_model_multiple_returns, wasm_component_model_multiple_returns)
             ("threads", threads, wasm_threads)
             ("gc", gc, wasm_gc)
             ("gc", reference_types, wasm_reference_types)
diff --git a/crates/environ/src/compile/module_types.rs b/crates/environ/src/compile/module_types.rs
index da8751e2f..74632539f 100644
--- a/crates/environ/src/compile/module_types.rs
+++ b/crates/environ/src/compile/module_types.rs
@@ -392,10 +392,18 @@ impl TypeConvert for WasmparserTypeConverter<'_> {
                         WasmCompositeType::Struct(_) => WasmHeapType::ConcreteStruct(index),
                     }
                 } else if let Some((wasmparser_types, _)) = self.rec_group_context.as_ref() {
-                    match &wasmparser_types[id].composite_type {
-                        wasmparser::CompositeType::Array(_) => WasmHeapType::ConcreteArray(index),
-                        wasmparser::CompositeType::Func(_) => WasmHeapType::ConcreteFunc(index),
-                        wasmparser::CompositeType::Struct(_) => WasmHeapType::ConcreteStruct(index),
+                    let wasmparser_ty = &wasmparser_types[id].composite_type;
+                    assert!(!wasmparser_ty.shared);
+                    match &wasmparser_ty.inner {
+                        wasmparser::CompositeInnerType::Array(_) => {
+                            WasmHeapType::ConcreteArray(index)
+                        }
+                        wasmparser::CompositeInnerType::Func(_) => {
+                            WasmHeapType::ConcreteFunc(index)
+                        }
+                        wasmparser::CompositeInnerType::Struct(_) => {
+                            WasmHeapType::ConcreteStruct(index)
+                        }
                     }
                 } else {
                     panic!("forward reference to type outside of rec group?")
@@ -424,10 +432,18 @@ impl TypeConvert for WasmparserTypeConverter<'_> {
                         .rec_group_elements(*rec_group)
                         .nth(rec_group_index)
                         .unwrap();
-                    match &parser_types[id].composite_type {
-                        wasmparser::CompositeType::Array(_) => WasmHeapType::ConcreteArray(index),
-                        wasmparser::CompositeType::Func(_) => WasmHeapType::ConcreteFunc(index),
-                        wasmparser::CompositeType::Struct(_) => WasmHeapType::ConcreteStruct(index),
+                    let wasmparser_ty = &parser_types[id].composite_type;
+                    assert!(!wasmparser_ty.shared);
+                    match &wasmparser_ty.inner {
+                        wasmparser::CompositeInnerType::Array(_) => {
+                            WasmHeapType::ConcreteArray(index)
+                        }
+                        wasmparser::CompositeInnerType::Func(_) => {
+                            WasmHeapType::ConcreteFunc(index)
+                        }
+                        wasmparser::CompositeInnerType::Struct(_) => {
+                            WasmHeapType::ConcreteStruct(index)
+                        }
                     }
                 } else {
                     panic!("forward reference to type outside of rec group?")
diff --git a/crates/fuzzing/src/generators/table_ops.rs b/crates/fuzzing/src/generators/table_ops.rs
index 0139d1c8d..aa0bdb134 100644
--- a/crates/fuzzing/src/generators/table_ops.rs
+++ b/crates/fuzzing/src/generators/table_ops.rs
@@ -86,6 +86,7 @@ impl TableOps {
             minimum: self.table_size as u64,
             maximum: None,
             table64: false,
+            shared: false,
         });
 
         // Define our globals.
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index 0c22a2e70..e4fc74c3f 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -1723,14 +1723,15 @@ pub trait TypeConvert {
     }
 
     fn convert_composite_type(&self, ty: &wasmparser::CompositeType) -> WasmCompositeType {
-        match ty {
-            wasmparser::CompositeType::Func(f) => {
+        assert!(!ty.shared);
+        match &ty.inner {
+            wasmparser::CompositeInnerType::Func(f) => {
                 WasmCompositeType::Func(self.convert_func_type(f))
             }
-            wasmparser::CompositeType::Array(a) => {
+            wasmparser::CompositeInnerType::Array(a) => {
                 WasmCompositeType::Array(self.convert_array_type(a))
             }
-            wasmparser::CompositeType::Struct(s) => {
+            wasmparser::CompositeInnerType::Struct(s) => {
                 WasmCompositeType::Struct(self.convert_struct_type(s))
             }
         }
diff --git a/crates/wasmtime/src/config.rs b/crates/wasmtime/src/config.rs
index ecb14717f..9fdfded73 100644
--- a/crates/wasmtime/src/config.rs
+++ b/crates/wasmtime/src/config.rs
@@ -996,6 +996,17 @@ impl Config {
         self
     }
 
+    /// Configures whether components support more than one return value for functions.
+    ///
+    /// This is part of the transition plan in
+    /// https://github.com/WebAssembly/component-model/pull/368.
+    #[cfg(feature = "component-model")]
+    pub fn wasm_component_model_multiple_returns(&mut self, enable: bool) -> &mut Self {
+        self.features
+            .set(WasmFeatures::COMPONENT_MODEL_MULTIPLE_RETURNS, enable);
+        self
+    }
+
     /// Configures which compilation strategy will be used for wasm modules.
     ///
     /// This method can be used to configure which compiler is used for wasm
diff --git a/crates/wasmtime/src/engine/serialization.rs b/crates/wasmtime/src/engine/serialization.rs
index c9e86cdb0..9ec83354c 100644
--- a/crates/wasmtime/src/engine/serialization.rs
+++ b/crates/wasmtime/src/engine/serialization.rs
@@ -203,6 +203,7 @@ struct WasmFeatures {
     gc: bool,
     custom_page_sizes: bool,
     component_model_more_flags: bool,
+    component_model_multiple_returns: bool,
 }
 
 impl Metadata<'_> {
@@ -229,6 +230,8 @@ impl Metadata<'_> {
             component_model_values,
             component_model_nested_names,
             component_model_more_flags,
+            component_model_multiple_returns,
+            legacy_exceptions,
 
             // Always on; we don't currently have knobs for these.
             mutable_global: _,
@@ -244,6 +247,7 @@ impl Metadata<'_> {
         assert!(!component_model_values);
         assert!(!component_model_nested_names);
         assert!(!shared_everything_threads);
+        assert!(!legacy_exceptions);
 
         Metadata {
             target: engine.compiler().triple().to_string(),
@@ -267,6 +271,7 @@ impl Metadata<'_> {
                 gc,
                 custom_page_sizes,
                 component_model_more_flags,
+                component_model_multiple_returns,
             },
         }
     }
@@ -473,6 +478,7 @@ impl Metadata<'_> {
             gc,
             custom_page_sizes,
             component_model_more_flags,
+            component_model_multiple_returns,
         } = self.features;
 
         use wasmparser::WasmFeatures as F;
@@ -559,6 +565,11 @@ impl Metadata<'_> {
             other.contains(F::COMPONENT_MODEL_MORE_FLAGS),
             "WebAssembly component model support for more than 32 flags",
         )?;
+        Self::check_bool(
+            component_model_multiple_returns,
+            other.contains(F::COMPONENT_MODEL_MULTIPLE_RETURNS),
+            "WebAssembly component model support for multiple returns",
+        )?;
 
         Ok(())
     }
diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
index b304b8781..0f63eabac 100644
--- a/supply-chain/imports.lock
+++ b/supply-chain/imports.lock
@@ -2145,6 +2145,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-encoder]]
+version = "0.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-metadata]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -2211,6 +2217,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasm-metadata]]
+version = "0.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasm-mutate]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -2349,6 +2361,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasmparser]]
+version = "0.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmprinter]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -2415,6 +2433,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wasmprinter]]
+version = "0.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wasmtime]]
 version = "18.0.2"
 when = "2024-02-28"
@@ -3171,6 +3195,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wast]]
+version = "214.0.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wat]]
 version = "1.201.0"
 when = "2024-02-27"
@@ -3237,6 +3267,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wat]]
+version = "1.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wiggle]]
 version = "18.0.2"
 when = "2024-02-28"
@@ -3555,6 +3591,12 @@ when = "2024-06-28"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-bindgen]]
+version = "0.28.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-bindgen-core]]
 version = "0.20.0"
 when = "2024-02-29"
@@ -3585,6 +3627,12 @@ when = "2024-06-28"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-bindgen-core]]
+version = "0.28.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-bindgen-rt]]
 version = "0.22.0"
 when = "2024-03-11"
@@ -3609,6 +3657,12 @@ when = "2024-06-28"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-bindgen-rt]]
+version = "0.28.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-bindgen-rust]]
 version = "0.20.0"
 when = "2024-02-29"
@@ -3639,6 +3693,12 @@ when = "2024-06-28"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-bindgen-rust]]
+version = "0.28.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-bindgen-rust-macro]]
 version = "0.20.0"
 when = "2024-02-29"
@@ -3669,6 +3729,12 @@ when = "2024-06-28"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-bindgen-rust-macro]]
+version = "0.28.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-component]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -3735,6 +3801,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-component]]
+version = "0.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.wit-parser]]
 version = "0.201.0"
 when = "2024-02-27"
@@ -3801,6 +3873,12 @@ when = "2024-06-27"
 user-id = 73222
 user-login = "wasmtime-publish"
 
+[[publisher.wit-parser]]
+version = "0.214.0"
+when = "2024-07-16"
+user-id = 73222
+user-login = "wasmtime-publish"
+
 [[publisher.witx]]
 version = "0.9.1"
 when = "2021-06-22"


Test patch:
diff --git a/tests/all/component_model/func.rs b/tests/all/component_model/func.rs
index b7481df02..0483ea643 100644
--- a/tests/all/component_model/func.rs
+++ b/tests/all/component_model/func.rs
@@ -5,7 +5,7 @@ use anyhow::Result;
 use std::rc::Rc;
 use std::sync::Arc;
 use wasmtime::component::*;
-use wasmtime::{Store, StoreContextMut, Trap};
+use wasmtime::{Config, Engine, Store, StoreContextMut, Trap};
 
 const CANON_32BIT_NAN: u32 = 0b01111111110000000000000000000000;
 const CANON_64BIT_NAN: u64 = 0b0111111111111000000000000000000000000000000000000000000000000000;
@@ -83,7 +83,9 @@ fn typecheck() -> Result<()> {
         )
     "#;
 
-    let engine = super::engine();
+    let mut config = Config::new();
+    config.wasm_component_model_multiple_returns(true);
+    let engine = Engine::new(&config)?;
     let component = Component::new(&engine, component)?;
     let mut store = Store::new(&engine, ());
     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
@@ -874,8 +876,7 @@ fn many_parameters() -> Result<()> {
                 (param "pc" (list char))     ;; offset 56, size 8
                 (param "pd" (list string))   ;; offset 64, size 8
 
-                (result "all-memory" (list u8))
-                (result "pointer" u32)
+                (result (tuple (list u8) u32))
             ))
             (func (export "many-param") (type $t)
                 (canon lift
@@ -905,7 +906,7 @@ fn many_parameters() -> Result<()> {
         &[bool],
         &[char],
         &[&str],
-    ), (WasmList<u8>, u32)>(&mut store, "many-param")?;
+    ), ((WasmList<u8>, u32),)>(&mut store, "many-param")?;
 
     let input = (
         -100,
@@ -929,7 +930,7 @@ fn many_parameters() -> Result<()> {
         ]
         .as_slice(),
     );
-    let (memory, pointer) = func.call(&mut store, input)?;
+    let ((memory, pointer),) = func.call(&mut store, input)?;
     let memory = memory.as_le_slice(&store);
 
     let mut actual = &memory[pointer as usize..][..72];
@@ -1246,7 +1247,7 @@ fn char_bool_memory() -> Result<()> {
             )
             (core instance $i (instantiate $m))
 
-            (func (export "ret-tuple") (param "a" u32) (param "b" u32) (result "c" bool) (result "d" char)
+            (func (export "ret-tuple") (param "a" u32) (param "b" u32) (result (tuple bool char))
                 (canon lift (core func $i "ret-tuple")
                     (memory $i "memory")
                     (realloc (func $i "realloc")))
@@ -1258,17 +1259,17 @@ fn char_bool_memory() -> Result<()> {
     let component = Component::new(&engine, component)?;
     let mut store = Store::new(&engine, ());
     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
-    let func = instance.get_typed_func::<(u32, u32), (bool, char)>(&mut store, "ret-tuple")?;
+    let func = instance.get_typed_func::<(u32, u32), ((bool, char),)>(&mut store, "ret-tuple")?;
 
-    let ret = func.call(&mut store, (0, 'a' as u32))?;
+    let (ret,) = func.call(&mut store, (0, 'a' as u32))?;
     assert_eq!(ret, (false, 'a'));
     func.post_return(&mut store)?;
 
-    let ret = func.call(&mut store, (1, '🍰' as u32))?;
+    let (ret,) = func.call(&mut store, (1, '🍰' as u32))?;
     assert_eq!(ret, (true, '🍰'));
     func.post_return(&mut store)?;
 
-    let ret = func.call(&mut store, (2, 'a' as u32))?;
+    let (ret,) = func.call(&mut store, (2, 'a' as u32))?;
     assert_eq!(ret, (true, 'a'));
     func.post_return(&mut store)?;
 
@@ -1441,13 +1442,13 @@ fn option() -> Result<()> {
             )
             (core instance $i (instantiate $m))
 
-            (func (export "option-u8-to-tuple") (param "a" (option u8)) (result "a" u32) (result "b" u32)
+            (func (export "option-u8-to-tuple") (param "a" (option u8)) (result (tuple u32 u32))
                 (canon lift (core func $i "pass1") (memory $i "memory"))
             )
-            (func (export "option-u32-to-tuple") (param "a" (option u32)) (result "a" u32) (result "b" u32)
+            (func (export "option-u32-to-tuple") (param "a" (option u32)) (result (tuple u32 u32))
                 (canon lift (core func $i "pass1") (memory $i "memory"))
             )
-            (func (export "option-string-to-tuple") (param "a" (option string)) (result "a" u32) (result "b" string)
+            (func (export "option-string-to-tuple") (param "a" (option string)) (result (tuple u32 string))
                 (canon lift
                     (core func $i "pass2")
                     (memory $i "memory")
@@ -1479,38 +1480,43 @@ fn option() -> Result<()> {
     let linker = Linker::new(&engine);
     let instance = linker.instantiate(&mut store, &component)?;
 
-    let option_u8_to_tuple =
-        instance.get_typed_func::<(Option<u8>,), (u32, u32)>(&mut store, "option-u8-to-tuple")?;
-    assert_eq!(option_u8_to_tuple.call(&mut store, (None,))?, (0, 0));
+    let option_u8_to_tuple = instance
+        .get_typed_func::<(Option<u8>,), ((u32, u32),)>(&mut store, "option-u8-to-tuple")?;
+    assert_eq!(option_u8_to_tuple.call(&mut store, (None,))?, ((0, 0),));
     option_u8_to_tuple.post_return(&mut store)?;
-    assert_eq!(option_u8_to_tuple.call(&mut store, (Some(0),))?, (1, 0));
+    assert_eq!(option_u8_to_tuple.call(&mut store, (Some(0),))?, ((1, 0),));
     option_u8_to_tuple.post_return(&mut store)?;
-    assert_eq!(option_u8_to_tuple.call(&mut store, (Some(100),))?, (1, 100));
+    assert_eq!(
+        option_u8_to_tuple.call(&mut store, (Some(100),))?,
+        ((1, 100),)
+    );
     option_u8_to_tuple.post_return(&mut store)?;
 
-    let option_u32_to_tuple =
-        instance.get_typed_func::<(Option<u32>,), (u32, u32)>(&mut store, "option-u32-to-tuple")?;
-    assert_eq!(option_u32_to_tuple.call(&mut store, (None,))?, (0, 0));
+    let option_u32_to_tuple = instance
+        .get_typed_func::<(Option<u32>,), ((u32, u32),)>(&mut store, "option-u32-to-tuple")?;
+    assert_eq!(option_u32_to_tuple.call(&mut store, (None,))?, ((0, 0),));
     option_u32_to_tuple.post_return(&mut store)?;
-    assert_eq!(option_u32_to_tuple.call(&mut store, (Some(0),))?, (1, 0));
+    assert_eq!(option_u32_to_tuple.call(&mut store, (Some(0),))?, ((1, 0),));
     option_u32_to_tuple.post_return(&mut store)?;
     assert_eq!(
         option_u32_to_tuple.call(&mut store, (Some(100),))?,
-        (1, 100)
+        ((1, 100),)
     );
     option_u32_to_tuple.post_return(&mut store)?;
 
-    let option_string_to_tuple = instance
-        .get_typed_func::<(Option<&str>,), (u32, WasmStr)>(&mut store, "option-string-to-tuple")?;
-    let (a, b) = option_string_to_tuple.call(&mut store, (None,))?;
+    let option_string_to_tuple = instance.get_typed_func::<(Option<&str>,), ((u32, WasmStr),)>(
+        &mut store,
+        "option-string-to-tuple",
+    )?;
+    let ((a, b),) = option_string_to_tuple.call(&mut store, (None,))?;
     assert_eq!(a, 0);
     assert_eq!(b.to_str(&store)?, "");
     option_string_to_tuple.post_return(&mut store)?;
-    let (a, b) = option_string_to_tuple.call(&mut store, (Some(""),))?;
+    let ((a, b),) = option_string_to_tuple.call(&mut store, (Some(""),))?;
     assert_eq!(a, 1);
     assert_eq!(b.to_str(&store)?, "");
     option_string_to_tuple.post_return(&mut store)?;
-    let (a, b) = option_string_to_tuple.call(&mut store, (Some("hello"),))?;
+    let ((a, b),) = option_string_to_tuple.call(&mut store, (Some("hello"),))?;
     assert_eq!(a, 1);
     assert_eq!(b.to_str(&store)?, "hello");
     option_string_to_tuple.post_return(&mut store)?;
@@ -1613,11 +1619,11 @@ fn expected() -> Result<()> {
             (func (export "take-expected-unit") (param "a" (result)) (result u32)
                 (canon lift (core func $i "pass0"))
             )
-            (func (export "take-expected-u8-f32") (param "a" (result u8 (error float32))) (result "a" u32) (result "b" u32)
+            (func (export "take-expected-u8-f32") (param "a" (result u8 (error float32))) (result (tuple u32 u32))
                 (canon lift (core func $i "pass1") (memory $i "memory"))
             )
             (type $list (list u8))
-            (func (export "take-expected-string") (param "a" (result string (error $list))) (result "a" u32) (result "b" string)
+            (func (export "take-expected-string") (param "a" (result string (error $list))) (result (tuple u32 string))
                 (canon lift
                     (core func $i "pass2")
                     (memory $i "memory")
@@ -1650,24 +1656,25 @@ fn expected() -> Result<()> {
     take_expected_unit.post_return(&mut store)?;
 
     let take_expected_u8_f32 = instance
-        .get_typed_func::<(Result<u8, f32>,), (u32, u32)>(&mut store, "take-expected-u8-f32")?;
-    assert_eq!(take_expected_u8_f32.call(&mut store, (Ok(1),))?, (0, 1));
+        .get_typed_func::<(Result<u8, f32>,), ((u32, u32),)>(&mut store, "take-expected-u8-f32")?;
+    assert_eq!(take_expected_u8_f32.call(&mut store, (Ok(1),))?, ((0, 1),));
     take_expected_u8_f32.post_return(&mut store)?;
     assert_eq!(
         take_expected_u8_f32.call(&mut store, (Err(2.0),))?,
-        (1, 2.0f32.to_bits())
+        ((1, 2.0f32.to_bits()),)
     );
     take_expected_u8_f32.post_return(&mut store)?;
 
-    let take_expected_string = instance.get_typed_func::<(Result<&str, &[u8]>,), (u32, WasmStr)>(
-        &mut store,
-        "take-expected-string",
-    )?;
-    let (a, b) = take_expected_string.call(&mut store, (Ok("hello"),))?;
+    let take_expected_string = instance
+        .get_typed_func::<(Result<&str, &[u8]>,), ((u32, WasmStr),)>(
+            &mut store,
+            "take-expected-string",
+        )?;
+    let ((a, b),) = take_expected_string.call(&mut store, (Ok("hello"),))?;
     assert_eq!(a, 0);
     assert_eq!(b.to_str(&store)?, "hello");
     take_expected_string.post_return(&mut store)?;
-    let (a, b) = take_expected_string.call(&mut store, (Err(b"goodbye"),))?;
+    let ((a, b),) = take_expected_string.call(&mut store, (Err(b"goodbye"),))?;
     assert_eq!(a, 1);
     assert_eq!(b.to_str(&store)?, "goodbye");
     take_expected_string.post_return(&mut store)?;
@@ -1746,9 +1753,7 @@ fn fancy_list() -> Result<()> {
             (type $input (list (tuple $a $b)))
             (func (export "take")
                 (param "a" $input)
-                (result "ptr" u32)
-                (result "len" u32)
-                (result "list" (list u8))
+                (result (tuple u32 u32 (list u8)))
                 (canon lift
                     (core func $i "take")
                     (memory $i "memory")
@@ -1764,7 +1769,7 @@ fn fancy_list() -> Result<()> {
     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
 
     let func = instance
-        .get_typed_func::<(&[(Option<u8>, Result<(), &str>)],), (u32, u32, WasmList<u8>)>(
+        .get_typed_func::<(&[(Option<u8>, Result<(), &str>)],), ((u32, u32, WasmList<u8>),)>(
             &mut store, "take",
         )?;
 
@@ -1773,7 +1778,7 @@ fn fancy_list() -> Result<()> {
         (Some(2), Err("hello there")),
         (Some(200), Err("general kenobi")),
     ];
-    let (ptr, len, list) = func.call(&mut store, (&input,))?;
+    let ((ptr, len, list),) = func.call(&mut store, (&input,))?;
     let memory = list.as_le_slice(&store);
     let ptr = usize::try_from(ptr).unwrap();
     let len = usize::try_from(len).unwrap();