Repository: bytecodealliance/wasm-tools
Pull request #2050 (2025-02-13 06:07:36)

Remove support for 33+ flags and multiple returns
This commit removes the feature gates of supporting 33-or-more flags in the component model and also being able to support named or multiple return types. These have been gated to return an error for some time now and no issues have arisen so now seems as good a time as any to remove the internal implementation details. This simplifies the representation of function return types and is intended to help make the internals here easier to understand for newcomers.


Patch:
diff --git a/crates/wasm-compose/src/encoding.rs b/crates/wasm-compose/src/encoding.rs
index a9bd70fa..bcbcfd89 100644
--- a/crates/wasm-compose/src/encoding.rs
+++ b/crates/wasm-compose/src/encoding.rs
@@ -476,26 +476,12 @@ impl<'a> TypeEncoder<'a> {
             .map(|(name, ty)| (name.as_str(), self.component_val_type(state, *ty)))
             .collect::<Vec<_>>();
 
-        let results = ty
-            .results
-            .iter()
-            .map(|(name, ty)| (name.as_deref(), self.component_val_type(state, *ty)))
-            .collect::<Vec<_>>();
+        let result = ty.result.map(|ty| self.component_val_type(state, ty));
 
         let index = state.cur.encodable.type_count();
         let mut f = state.cur.encodable.ty().function();
 
-        f.params(params);
-
-        if results.len() == 1 && results[0].0.is_none() {
-            f.result(results[0].1);
-        } else {
-            f.results(
-                results
-                    .into_iter()
-                    .map(|(name, ty)| (name.unwrap().as_str(), ty)),
-            );
-        }
+        f.params(params).result(result);
 
         index
     }
@@ -1239,12 +1225,7 @@ impl DependencyRegistrar<'_, '_> {
 
     fn func(&mut self, ty: ComponentFuncTypeId) {
         let ty = &self.types[ty];
-        for ty in ty
-            .params
-            .iter()
-            .map(|p| p.1)
-            .chain(ty.results.iter().map(|p| p.1))
-        {
+        for ty in ty.params.iter().map(|p| p.1).chain(ty.result) {
             self.val_type(ty);
         }
     }
diff --git a/crates/wasm-encoder/src/component/imports.rs b/crates/wasm-encoder/src/component/imports.rs
index 9bd67168..c47baa34 100644
--- a/crates/wasm-encoder/src/component/imports.rs
+++ b/crates/wasm-encoder/src/component/imports.rs
@@ -96,7 +96,7 @@ impl Encode for ComponentTypeRef {
 ///       ("b", PrimitiveValType::String)
 ///     ]
 ///   )
-///   .result(PrimitiveValType::String);
+///   .result(Some(PrimitiveValType::String.into()));
 ///
 /// // This imports a function named `f` with the type defined above
 /// let mut imports = ComponentImportSection::new();
diff --git a/crates/wasm-encoder/src/component/types.rs b/crates/wasm-encoder/src/component/types.rs
index 505e30b3..43285e71 100644
--- a/crates/wasm-encoder/src/component/types.rs
+++ b/crates/wasm-encoder/src/component/types.rs
@@ -401,38 +401,19 @@ impl<'a> ComponentFuncTypeEncoder<'a> {
     ///
     /// This method will panic if the function is called twice, called before
     /// the `params` method, or called in addition to the `results` method.
-    pub fn result(&mut self, ty: impl Into<ComponentValType>) -> &mut Self {
+    pub fn result(&mut self, ty: Option<ComponentValType>) -> &mut Self {
         assert!(self.params_encoded);
         assert!(!self.results_encoded);
         self.results_encoded = true;
-        self.sink.push(0x00);
-        ty.into().encode(self.sink);
-        self
-    }
-
-    /// Defines named results.
-    ///
-    /// This method cannot be used with `result`.
-    ///
-    /// # Panics
-    ///
-    /// This method will panic if the function is called twice, called before
-    /// the `params` method, or called in addition to the `result` method.
-    pub fn results<'b, R, T>(&mut self, results: R) -> &mut Self
-    where
-        R: IntoIterator<Item = (&'b str, T)>,
-        R::IntoIter: ExactSizeIterator,
-        T: Into<ComponentValType>,
-    {
-        assert!(self.params_encoded);
-        assert!(!self.results_encoded);
-        self.results_encoded = true;
-        self.sink.push(0x01);
-        let results = results.into_iter();
-        results.len().encode(self.sink);
-        for (name, ty) in results {
-            name.encode(self.sink);
-            ty.into().encode(self.sink);
+        match ty {
+            Some(ty) => {
+                self.sink.push(0x00);
+                ty.encode(self.sink);
+            }
+            None => {
+                self.sink.push(0x01);
+                self.sink.push(0x00);
+            }
         }
         self
     }
@@ -709,7 +690,7 @@ impl ComponentDefinedTypeEncoder<'_> {
 ///       ("b", PrimitiveValType::String)
 ///     ]
 ///   )
-///   .result(PrimitiveValType::String);
+///   .result(Some(PrimitiveValType::String.into()));
 ///
 /// let mut component = Component::new();
 /// component.section(&types);
diff --git a/crates/wasm-encoder/src/reencode/component.rs b/crates/wasm-encoder/src/reencode/component.rs
index 12b08130..91c53e5a 100644
--- a/crates/wasm-encoder/src/reencode/component.rs
+++ b/crates/wasm-encoder/src/reencode/component.rs
@@ -735,18 +735,8 @@ pub mod component_utils {
                 .into_iter()
                 .map(|(name, ty)| (name, reencoder.component_val_type(ty))),
         );
-        match ty.results {
-            wasmparser::ComponentFuncResult::Unnamed(ty) => {
-                func.result(reencoder.component_val_type(ty));
-            }
-            wasmparser::ComponentFuncResult::Named(list) => {
-                func.results(
-                    Vec::from(list)
-                        .into_iter()
-                        .map(|(name, ty)| (name, reencoder.component_val_type(ty))),
-                );
-            }
-        }
+        let result = ty.result.map(|ty| reencoder.component_val_type(ty));
+        func.result(result);
         Ok(())
     }
 
diff --git a/crates/wasm-metadata/src/add_metadata.rs b/crates/wasm-metadata/src/add_metadata.rs
index c402eede..e89a6da1 100644
--- a/crates/wasm-metadata/src/add_metadata.rs
+++ b/crates/wasm-metadata/src/add_metadata.rs
@@ -1,5 +1,5 @@
 use crate::{
-    rewrite_wasm, Author, Description, Homepage, Licenses, Producers, Revision, Source, Version,
+    rewrite_wasm, Authors, Description, Homepage, Licenses, Producers, Revision, Source, Version,
 };
 
 use anyhow::Result;
@@ -30,7 +30,7 @@ pub struct AddMetadata {
     /// Contact details of the people or organization responsible,
     /// encoded as a freeform string.
     #[cfg_attr(feature = "clap", clap(long, value_name = "NAME"))]
-    pub author: Option<Author>,
+    pub authors: Option<Authors>,
 
     /// A human-readable description of the binary
     #[cfg_attr(feature = "clap", clap(long, value_name = "NAME"))]
@@ -72,7 +72,7 @@ impl AddMetadata {
         rewrite_wasm(
             &self.name,
             &Producers::from_meta(self),
-            &self.author,
+            &self.authors,
             &self.description,
             &self.licenses,
             &self.source,
diff --git a/crates/wasm-metadata/src/lib.rs b/crates/wasm-metadata/src/lib.rs
index 41958407..108b60ee 100644
--- a/crates/wasm-metadata/src/lib.rs
+++ b/crates/wasm-metadata/src/lib.rs
@@ -5,7 +5,7 @@
 pub use add_metadata::AddMetadata;
 pub use metadata::Metadata;
 pub use names::{ComponentNames, ModuleNames};
-pub use oci_annotations::{Author, Description, Homepage, Licenses, Revision, Source, Version};
+pub use oci_annotations::{Authors, Description, Homepage, Licenses, Revision, Source, Version};
 pub use payload::Payload;
 pub use producers::{Producers, ProducersField};
 
diff --git a/crates/wasm-metadata/src/metadata.rs b/crates/wasm-metadata/src/metadata.rs
index 758304d5..7934de9b 100644
--- a/crates/wasm-metadata/src/metadata.rs
+++ b/crates/wasm-metadata/src/metadata.rs
@@ -1,7 +1,7 @@
 use serde_derive::Serialize;
 use std::ops::Range;
 
-use crate::{Author, Description, Homepage, Licenses, Producers, Revision, Source, Version};
+use crate::{Authors, Description, Homepage, Licenses, Producers, Revision, Source, Version};
 
 /// Metadata associated with a Wasm Component or Module
 #[derive(Debug, Serialize, Default)]
@@ -11,8 +11,8 @@ pub struct Metadata {
     pub name: Option<String>,
     /// The component's producers section, if any.
     pub producers: Option<Producers>,
-    /// The component's author section, if any.
-    pub author: Option<Author>,
+    /// The component's authors section, if any.
+    pub authors: Option<Authors>,
     /// Human-readable description of the binary
     pub description: Option<Description>,
     /// License(s) under which contained software is distributed as an SPDX License Expression.
diff --git a/crates/wasm-metadata/src/oci_annotations/author.rs b/crates/wasm-metadata/src/oci_annotations/authors.rs
similarity index 81%
rename from crates/wasm-metadata/src/oci_annotations/author.rs
rename to crates/wasm-metadata/src/oci_annotations/authors.rs
index ae794829..8cfa107e 100644
--- a/crates/wasm-metadata/src/oci_annotations/author.rs
+++ b/crates/wasm-metadata/src/oci_annotations/authors.rs
@@ -10,13 +10,13 @@ use wasmparser::CustomSectionReader;
 /// Contact details of the people or organization responsible,
 /// encoded as a freeform string.
 #[derive(Debug, Clone, PartialEq)]
-pub struct Author(CustomSection<'static>);
+pub struct Authors(CustomSection<'static>);
 
-impl Author {
+impl Authors {
     /// Create a new instance of `Author`.
     pub fn new<S: Into<Cow<'static, str>>>(s: S) -> Self {
         Self(CustomSection {
-            name: "author".into(),
+            name: "authors".into(),
             data: match s.into() {
                 Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()),
                 Cow::Owned(s) => Cow::Owned(s.into()),
@@ -27,15 +27,15 @@ impl Author {
     /// Parse an `author` custom section from a wasm binary.
     pub(crate) fn parse_custom_section(reader: &CustomSectionReader<'_>) -> Result<Self> {
         ensure!(
-            reader.name() == "author",
-            "The `author` custom section should have a name of 'author'"
+            reader.name() == "authors",
+            "The `authors` custom section should have a name of 'authors'"
         );
         let data = String::from_utf8(reader.data().to_owned())?;
         Ok(Self::new(data))
     }
 }
 
-impl FromStr for Author {
+impl FromStr for Authors {
     type Err = Error;
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -43,7 +43,7 @@ impl FromStr for Author {
     }
 }
 
-impl Serialize for Author {
+impl Serialize for Authors {
     fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
     where
         S: serde::Serializer,
@@ -52,7 +52,7 @@ impl Serialize for Author {
     }
 }
 
-impl Display for Author {
+impl Display for Authors {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // NOTE: this will never panic since we always guarantee the data is
         // encoded as utf8, even if we internally store it as [u8].
@@ -61,19 +61,19 @@ impl Display for Author {
     }
 }
 
-impl ComponentSection for Author {
+impl ComponentSection for Authors {
     fn id(&self) -> u8 {
         ComponentSection::id(&self.0)
     }
 }
 
-impl Section for Author {
+impl Section for Authors {
     fn id(&self) -> u8 {
         Section::id(&self.0)
     }
 }
 
-impl Encode for Author {
+impl Encode for Authors {
     fn encode(&self, sink: &mut Vec<u8>) {
         self.0.encode(sink);
     }
@@ -88,13 +88,13 @@ mod test {
     #[test]
     fn roundtrip() {
         let mut component = Component::new();
-        component.section(&Author::new("Nori Cat"));
+        component.section(&Authors::new("Nori Cat"));
         let component = component.finish();
 
         let mut parsed = false;
         for section in wasmparser::Parser::new(0).parse_all(&component) {
             if let Payload::CustomSection(reader) = section.unwrap() {
-                let author = Author::parse_custom_section(&reader).unwrap();
+                let author = Authors::parse_custom_section(&reader).unwrap();
                 assert_eq!(author.to_string(), "Nori Cat");
                 parsed = true;
             }
@@ -104,7 +104,7 @@ mod test {
 
     #[test]
     fn serialize() {
-        let author = Author::new("Chashu Cat");
+        let author = Authors::new("Chashu Cat");
         let json = serde_json::to_string(&author).unwrap();
         assert_eq!(r#""Chashu Cat""#, json);
     }
diff --git a/crates/wasm-metadata/src/oci_annotations/mod.rs b/crates/wasm-metadata/src/oci_annotations/mod.rs
index e9e08739..b1d2400e 100644
--- a/crates/wasm-metadata/src/oci_annotations/mod.rs
+++ b/crates/wasm-metadata/src/oci_annotations/mod.rs
@@ -15,7 +15,7 @@
 //!
 //! [OCI Annotations Spec]: https://specs.opencontainers.org/image-spec/annotations/
 
-pub use author::Author;
+pub use authors::Authors;
 pub use description::Description;
 pub use homepage::Homepage;
 pub use licenses::Licenses;
@@ -23,7 +23,7 @@ pub use revision::Revision;
 pub use source::Source;
 pub use version::Version;
 
-mod author;
+mod authors;
 mod description;
 mod homepage;
 mod licenses;
diff --git a/crates/wasm-metadata/src/payload.rs b/crates/wasm-metadata/src/payload.rs
index 36120797..e59bd00b 100644
--- a/crates/wasm-metadata/src/payload.rs
+++ b/crates/wasm-metadata/src/payload.rs
@@ -5,7 +5,7 @@ use serde_derive::Serialize;
 use wasmparser::{KnownCustom, Parser, Payload::*};
 
 use crate::{
-    Author, ComponentNames, Description, Homepage, Licenses, Metadata, ModuleNames, Producers,
+    Authors, ComponentNames, Description, Homepage, Licenses, Metadata, ModuleNames, Producers,
     Revision, Source,
 };
 
@@ -93,9 +93,11 @@ impl Payload {
                             .metadata_mut()
                             .producers = Some(producers);
                     }
-                    KnownCustom::Unknown if c.name() == "author" => {
-                        let a = Author::parse_custom_section(&c)?;
-                        let Metadata { author, .. } = output
+                    KnownCustom::Unknown if c.name() == "authors" => {
+                        let a = Authors::parse_custom_section(&c)?;
+                        let Metadata {
+                            authors: author, ..
+                        } = output
                             .last_mut()
                             .expect("non-empty metadata stack")
                             .metadata_mut();
diff --git a/crates/wasm-metadata/src/rewrite.rs b/crates/wasm-metadata/src/rewrite.rs
index 17dbd9ba..dce272a3 100644
--- a/crates/wasm-metadata/src/rewrite.rs
+++ b/crates/wasm-metadata/src/rewrite.rs
@@ -1,5 +1,5 @@
 use crate::{
-    Author, ComponentNames, Description, Homepage, Licenses, ModuleNames, Producers, Revision,
+    Authors, ComponentNames, Description, Homepage, Licenses, ModuleNames, Producers, Revision,
     Source,
 };
 use anyhow::Result;
@@ -11,7 +11,7 @@ use wasmparser::{KnownCustom, Parser, Payload::*};
 pub(crate) fn rewrite_wasm(
     add_name: &Option<String>,
     add_producers: &Producers,
-    add_author: &Option<Author>,
+    add_author: &Option<Authors>,
     add_description: &Option<Description>,
     add_licenses: &Option<Licenses>,
     add_source: &Option<Source>,
@@ -86,7 +86,7 @@ pub(crate) fn rewrite_wasm(
                     }
                     KnownCustom::Unknown if c.name() == "author" => {
                         if add_author.is_none() {
-                            let author = Author::parse_custom_section(c)?;
+                            let author = Authors::parse_custom_section(c)?;
                             author.append_to(&mut output);
                             continue;
                         }
diff --git a/crates/wasm-smith/src/component/encode.rs b/crates/wasm-smith/src/component/encode.rs
index 5579e8e5..e070654a 100644
--- a/crates/wasm-smith/src/component/encode.rs
+++ b/crates/wasm-smith/src/component/encode.rs
@@ -172,17 +172,7 @@ impl Type {
                 let mut f = enc.function();
 
                 f.params(func_ty.params.iter().map(|(name, ty)| (name.as_str(), *ty)));
-
-                if let Some(ty) = func_ty.unnamed_result_ty() {
-                    f.result(ty);
-                } else {
-                    f.results(
-                        func_ty
-                            .results
-                            .iter()
-                            .map(|(name, ty)| (name.as_deref().unwrap(), *ty)),
-                    );
-                }
+                f.result(func_ty.unnamed_result_ty());
             }
             Self::Component(comp_ty) => {
                 let mut enc_comp_ty = wasm_encoder::ComponentType::new();
diff --git a/crates/wasm-wave/src/value/wit.rs b/crates/wasm-wave/src/value/wit.rs
index 9ac77bdf..423090a6 100644
--- a/crates/wasm-wave/src/value/wit.rs
+++ b/crates/wasm-wave/src/value/wit.rs
@@ -20,9 +20,9 @@ pub fn resolve_wit_func_type(
 ) -> Result<value::FuncType, WasmValueError> {
     let resolver = TypeResolver { resolve };
     let params = resolver.resolve_params(&function.params)?;
-    let results = match &function.results {
-        wit_parser::Results::Named(results) => resolver.resolve_params(results)?,
-        wit_parser::Results::Anon(ty) => vec![("".into(), resolver.resolve_type(*ty)?)],
+    let results = match &function.result {
+        Some(ty) => vec![("".into(), resolver.resolve_type(*ty)?)],
+        None => Vec::new(),
     };
     value::FuncType::new(params, results)
 }
@@ -184,7 +184,7 @@ interface types {
     type uint8 = u8;
     no-results: func(a: uint8, b: string);
     one-result: func(c: uint8, d: string) -> uint8;
-    named-results: func(e: uint8, f: string) -> (x: u8, y: string);
+    named-results: func(e: uint8, f: string) -> tuple<u8, string>;
 }
                 "#,
             )
@@ -195,7 +195,7 @@ interface types {
             ("one-result", "func(c: u8, d: string) -> u8"),
             (
                 "named-results",
-                "func(e: u8, f: string) -> (x: u8, y: string)",
+                "func(e: u8, f: string) -> tuple<u8, string>",
             ),
         ] {
             let function = resolve
diff --git a/crates/wasmparser/src/features.rs b/crates/wasmparser/src/features.rs
index 53661b71..fdd693c9 100644
--- a/crates/wasmparser/src/features.rs
+++ b/crates/wasmparser/src/features.rs
@@ -197,10 +197,6 @@ define_wasm_features! {
         pub component_model_values: COMPONENT_MODEL_VALUES(1 << 21) = false;
         /// Support for the nested namespaces and projects in component model names.
         pub component_model_nested_names: COMPONENT_MODEL_NESTED_NAMES(1 << 22) = false;
-        /// Support for more than 32 flags per-type in the component model.
-        pub component_model_more_flags: COMPONENT_MODEL_MORE_FLAGS(1 << 23) = false;
-        /// Support for multiple return values in a component model function.
-        pub component_model_multiple_returns: COMPONENT_MODEL_MULTIPLE_RETURNS(1 << 24) = false;
         /// The WebAssembly legacy exception handling proposal (phase 1)
         ///
         /// # Note
diff --git a/crates/wasmparser/src/readers/component/types.rs b/crates/wasmparser/src/readers/component/types.rs
index 3a3da428..dfcd4e06 100644
--- a/crates/wasmparser/src/readers/component/types.rs
+++ b/crates/wasmparser/src/readers/component/types.rs
@@ -282,8 +282,15 @@ impl<'a> FromReader<'a> for ComponentType<'a> {
                 let params = reader
                     .read_iter(MAX_WASM_FUNCTION_PARAMS, "component function parameters")?
                     .collect::<Result<_>>()?;
-                let results = reader.read()?;
-                ComponentType::Func(ComponentFuncType { params, results })
+                let result = match reader.read_u8()? {
+                    0x00 => Some(reader.read()?),
+                    0x01 => match reader.read_u8()? {
+                        0x00 => None,
+                        x => return reader.invalid_leading_byte(x, "number of results"),
+                    },
+                    x => return reader.invalid_leading_byte(x, "component function results"),
+                };
+                ComponentType::Func(ComponentFuncType { params, result })
             }
             0x41 => ComponentType::Component(
                 reader
@@ -380,74 +387,13 @@ impl<'a> FromReader<'a> for InstanceTypeDeclaration<'a> {
     }
 }
 
-/// Represents the result type of a component function.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub enum ComponentFuncResult<'a> {
-    /// The function returns a singular, unnamed type.
-    Unnamed(ComponentValType),
-    /// The function returns zero or more named types.
-    Named(Box<[(&'a str, ComponentValType)]>),
-}
-
-impl<'a> FromReader<'a> for ComponentFuncResult<'a> {
-    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
-        Ok(match reader.read_u8()? {
-            0x00 => ComponentFuncResult::Unnamed(reader.read()?),
-            0x01 => ComponentFuncResult::Named(
-                reader
-                    .read_iter(MAX_WASM_FUNCTION_RETURNS, "component function results")?
-                    .collect::<Result<_>>()?,
-            ),
-            x => return reader.invalid_leading_byte(x, "component function results"),
-        })
-    }
-}
-
-impl ComponentFuncResult<'_> {
-    /// Gets the count of types returned by the function.
-    pub fn type_count(&self) -> usize {
-        match self {
-            Self::Unnamed(_) => 1,
-            Self::Named(vec) => vec.len(),
-        }
-    }
-
-    /// Iterates over the types returned by the function.
-    pub fn iter(&self) -> impl Iterator<Item = (Option<&str>, &ComponentValType)> {
-        enum Either<L, R> {
-            Left(L),
-            Right(R),
-        }
-
-        impl<L, R> Iterator for Either<L, R>
-        where
-            L: Iterator,
-            R: Iterator<Item = L::Item>,
-        {
-            type Item = L::Item;
-
-            fn next(&mut self) -> Option<Self::Item> {
-                match self {
-                    Either::Left(l) => l.next(),
-                    Either::Right(r) => r.next(),
-                }
-            }
-        }
-
-        match self {
-            Self::Unnamed(ty) => Either::Left(core::iter::once(ty).map(|ty| (None, ty))),
-            Self::Named(vec) => Either::Right(vec.iter().map(|(n, ty)| (Some(*n), ty))),
-        }
-    }
-}
-
 /// Represents a type of a function in a WebAssembly component.
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct ComponentFuncType<'a> {
     /// The function parameters.
     pub params: Box<[(&'a str, ComponentValType)]>,
     /// The function result.
-    pub results: ComponentFuncResult<'a>,
+    pub result: Option<ComponentValType>,
 }
 
 /// Represents a case in a variant type.
diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs
index 06aadcbe..c963abb7 100644
--- a/crates/wasmparser/src/validator/component.rs
+++ b/crates/wasmparser/src/validator/component.rs
@@ -346,7 +346,7 @@ impl ComponentState {
                 types.push(ty).into()
             }
             crate::ComponentType::Func(ty) => {
-                let ty = current(components).create_function_type(ty, types, features, offset)?;
+                let ty = current(components).create_function_type(ty, types, offset)?;
                 types.push(ty).into()
             }
             crate::ComponentType::Component(decls) => {
@@ -777,7 +777,7 @@ impl ComponentState {
         ty.params
             .iter()
             .map(|(_, ty)| ty)
-            .chain(ty.results.iter().map(|(_, ty)| ty))
+            .chain(&ty.result)
             .all(|ty| types.type_named_valtype(ty, set))
     }
 
@@ -1132,7 +1132,7 @@ impl ComponentState {
                     ))
                 })
                 .collect::<Result<_>>()?,
-            results: Box::new([]),
+            result: None,
         }
         .lower(types, Abi::LiftSync);
 
@@ -1869,12 +1869,12 @@ impl ComponentState {
             );
         }
 
-        if ft.results.len() as u32 != results {
+        if u32::from(ft.result.is_some()) != results {
             bail!(
                 offset,
                 "component start function has a result count of {results} \
                  but the function type has a result count of {type_results}",
-                type_results = ft.results.len(),
+                type_results = u32::from(ft.result.is_some()),
             );
         }
 
@@ -1887,8 +1887,8 @@ impl ComponentState {
                 })?;
         }
 
-        for (_, ty) in ft.results.iter() {
-            self.values.push((*ty, false));
+        if let Some(ty) = ft.result {
+            self.values.push((ty, false));
         }
 
         self.has_start = true;
@@ -2359,21 +2359,15 @@ impl ComponentState {
         &self,
         ty: crate::ComponentFuncType,
         types: &TypeList,
-        features: &WasmFeatures,
         offset: usize,
     ) -> Result<ComponentFuncType> {
         let mut info = TypeInfo::new();
 
-        if ty.results.type_count() > 1 && !features.component_model_multiple_returns() {
-            bail!(
-                offset,
-                "multiple returns on a function is now a gated feature \
-                 -- https://github.com/WebAssembly/component-model/pull/368"
-            );
-        }
-
         let mut set = Set::default();
-        set.reserve(core::cmp::max(ty.params.len(), ty.results.type_count()));
+        set.reserve(core::cmp::max(
+            ty.params.len(),
+            usize::from(ty.result.is_some()),
+        ));
 
         let params = ty
             .params
@@ -2396,39 +2390,23 @@ impl ComponentState {
 
         set.clear();
 
-        let results = ty
-            .results
-            .iter()
-            .map(|(name, ty)| {
-                let name = name
-                    .map(|name| {
-                        let name = to_kebab_str(name, "function result", offset)?;
-                        if !set.insert(name) {
-                            bail!(
-                                offset,
-                                "function result name `{name}` conflicts with previous result name `{prev}`",
-                                prev = set.get(name).unwrap(),
-                            );
-                        }
-
-                        Ok(name.to_owned())
-                    })
-                    .transpose()?;
-
-                let ty = self.create_component_val_type(*ty, offset)?;
+        let result = ty
+            .result
+            .map(|ty| {
+                let ty = self.create_component_val_type(ty, offset)?;
                 let ty_info = ty.info(types);
                 if ty_info.contains_borrow() {
                     bail!(offset, "function result cannot contain a `borrow` type");
                 }
                 info.combine(ty.info(types), offset)?;
-                Ok((name, ty))
+                Ok(ty)
             })
-            .collect::<Result<_>>()?;
+            .transpose()?;
 
         Ok(ComponentFuncType {
             info,
             params,
-            results,
+            result,
         })
     }
 
@@ -3266,6 +3244,9 @@ impl ComponentState {
         features: &WasmFeatures,
         offset: usize,
     ) -> Result<ComponentDefinedType> {
+        // Not currently used but it's convenient to have for future features,
+        // so suppress the unused variable warning.
+        let _ = features;
         match ty {
             crate::ComponentDefinedType::Primitive(ty) => Ok(ComponentDefinedType::Primitive(ty)),
             crate::ComponentDefinedType::Record(fields) => {
@@ -3281,7 +3262,7 @@ impl ComponentState {
                 self.create_tuple_type(tys.as_ref(), types, offset)
             }
             crate::ComponentDefinedType::Flags(names) => {
-                self.create_flags_type(names.as_ref(), features, offset)
+                self.create_flags_type(names.as_ref(), offset)
             }
             crate::ComponentDefinedType::Enum(cases) => {
                 self.create_enum_type(cases.as_ref(), offset)
@@ -3442,12 +3423,7 @@ impl ComponentState {
         Ok(ComponentDefinedType::Tuple(TupleType { info, types }))
     }
 
-    fn create_flags_type(
-        &self,
-        names: &[&str],
-        features: &WasmFeatures,
-        offset: usize,
-    ) -> Result<ComponentDefinedType> {
+    fn create_flags_type(&self, names: &[&str], offset: usize) -> Result<ComponentDefinedType> {
         let mut names_set = IndexSet::default();
         names_set.reserve(names.len());
 
@@ -3455,14 +3431,8 @@ impl ComponentState {
             bail!(offset, "flags must have at least one entry");
         }
 
-        if names.len() > 32 && !features.component_model_more_flags() {
-            bail!(
-                offset,
-                "cannot have more than 32 flags; this was previously \
-                 accepted and if this is required for your project please \
-                 leave a comment on \
-                 https://github.com/WebAssembly/component-model/issues/370"
-            );
+        if names.len() > 32 {
+            bail!(offset, "cannot have more than 32 flags");
         }
 
         for name in names {
@@ -3898,10 +3868,10 @@ impl ComponentNameContext {
             // must be named within this context to match `rname`
             ComponentNameKind::Constructor(rname) => {
                 let ty = func()?;
-                if ty.results.len() != 1 {
-                    bail!(offset, "function should return one value");
-                }
-                let ty = ty.results[0].1;
+                let ty = match ty.result {
+                    Some(result) => result,
+                    None => bail!(offset, "function should return one value"),
+                };
                 let resource = match ty {
                     ComponentValType::Primitive(_) => None,
                     ComponentValType::Type(ty) => match &types[ty] {
diff --git a/crates/wasmparser/src/validator/component_types.rs b/crates/wasmparser/src/validator/component_types.rs
index 76ab1ff5..bfea0fc0 100644
--- a/crates/wasmparser/src/validator/component_types.rs
+++ b/crates/wasmparser/src/validator/component_types.rs
@@ -879,8 +879,8 @@ pub struct ComponentFuncType {
     pub(crate) info: TypeInfo,
     /// The function parameters.
     pub params: Box<[(KebabString, ComponentValType)]>,
-    /// The function's results.
-    pub results: Box<[(Option<KebabString>, ComponentValType)]>,
+    /// The function's result.
+    pub result: Option<ComponentValType>,
 }
 
 impl TypeData for ComponentFuncType {
@@ -913,7 +913,10 @@ impl ComponentFuncType {
                 }
                 info.results.push(ValType::I32);
                 info.requires_memory = true;
-                info.requires_realloc = self.results.iter().any(|(_, ty)| ty.contains_ptr(types));
+                info.requires_realloc = self
+                    .result
+                    .map(|ty| ty.contains_ptr(types))
+                    .unwrap_or(false);
                 return info;
             }
             Abi::LowerSync => true,
@@ -956,7 +959,7 @@ impl ComponentFuncType {
         match abi {
             Abi::LowerAsync => unreachable!(),
             Abi::LowerSync | Abi::LiftSync => {
-                for (_, ty) in self.results.iter() {
+                if let Some(ty) = &self.result {
                     // Results of lowered functions that contains pointers must be
                     // allocated by the callee meaning that realloc is required.
                     // Results of lifted function are allocated by the guest which
@@ -976,7 +979,6 @@ impl ComponentFuncType {
                             assert!(info.results.push(ValType::I32));
                         }
                         info.requires_memory = true;
-                        break;
                     }
                 }
             }
@@ -2024,12 +2026,7 @@ impl TypeAlloc {
         set: &mut IndexSet<ResourceId>,
     ) {
         let i = &self[id];
-        for ty in i
-            .params
-            .iter()
-            .map(|(_, ty)| ty)
-            .chain(i.results.iter().map(|(_, ty)| ty))
-        {
+        for ty in i.params.iter().map(|(_, ty)| ty).chain(&i.result) {
             self.free_variables_valtype(ty, set);
         }
     }
@@ -2353,7 +2350,7 @@ where
             .params
             .iter_mut()
             .map(|(_, ty)| ty)
-            .chain(tmp.results.iter_mut().map(|(_, ty)| ty))
+            .chain(&mut tmp.result)
         {
             any_changed |= self.remap_valtype(ty, map);
         }
@@ -2710,14 +2707,6 @@ impl<'a> SubtypeCx<'a> {
                 a.params.len(),
             );
         }
-        if a.results.len() != b.results.len() {
-            bail!(
-                offset,
-                "expected {} results, found {}",
-                b.results.len(),
-                a.results.len(),
-            );
-        }
         for ((an, a), (bn, b)) in a.params.iter().zip(b.params.iter()) {
             if an != bn {
                 bail!(offset, "expected parameter named `{bn}`, found `{an}`");
@@ -2725,12 +2714,15 @@ impl<'a> SubtypeCx<'a> {
             self.component_val_type(a, b, offset)
                 .with_context(|| format!("type mismatch in function parameter `{an}`"))?;
         }
-        for ((an, a), (bn, b)) in a.results.iter().zip(b.results.iter()) {
-            if an != bn {
-                bail!(offset, "mismatched result names");
-            }
-            self.component_val_type(a, b, offset)
-                .with_context(|| "type mismatch with result type")?;
+
+        match (&a.result, &b.result) {
+            (Some(a), Some(b)) => self
+                .component_val_type(a, b, offset)
+                .with_context(|| "type mismatch with result type")?,
+            (None, None) => {}
+
+            (Some(_), None) => bail!(offset, "expected a result, found none"),
+            (None, Some(_)) => bail!(offset, "expected no result, found one"),
         }
         Ok(())
     }
diff --git a/crates/wasmprinter/src/component.rs b/crates/wasmprinter/src/component.rs
index 762af3f7..d7028932 100644
--- a/crates/wasmprinter/src/component.rs
+++ b/crates/wasmprinter/src/component.rs
@@ -457,13 +457,9 @@ impl Printer<'_, '_> {
             self.end_group()?;
         }
 
-        for (name, ty) in ty.results.iter() {
+        if let Some(ty) = &ty.result {
             self.result.write_str(" ")?;
             self.start_group("result ")?;
-            if let Some(name) = name {
-                self.print_str(name)?;
-                self.result.write_str(" ")?;
-            }
             self.print_component_val_type(state, ty)?;
             self.end_group()?;
         }
diff --git a/crates/wast/src/component/binary.rs b/crates/wast/src/component/binary.rs
index f8a86c8d..ac4f6682 100644
--- a/crates/wast/src/component/binary.rs
+++ b/crates/wast/src/component/binary.rs
@@ -76,11 +76,7 @@ fn encode_type(encoder: ComponentTypeEncoder, ty: &TypeDef) {
             let mut encoder = encoder.function();
             encoder.params(f.params.iter().map(|p| (p.name, &p.ty)));
 
-            if f.results.len() == 1 && f.results[0].name.is_none() {
-                encoder.result(&f.results[0].ty);
-            } else {
-                encoder.results(f.results.iter().map(|r| (r.name.unwrap_or(""), &r.ty)));
-            }
+            encoder.result(f.result.as_ref().map(|ty| ty.into()));
         }
         TypeDef::Component(c) => {
             encoder.component(&c.into());
diff --git a/crates/wast/src/component/expand.rs b/crates/wast/src/component/expand.rs
index abd95bb8..f2c3b3ca 100644
--- a/crates/wast/src/component/expand.rs
+++ b/crates/wast/src/component/expand.rs
@@ -599,8 +599,8 @@ impl<'a> Expander<'a> {
             self.expand_component_val_ty(&mut param.ty);
         }
 
-        for result in ty.results.iter_mut() {
-            self.expand_component_val_ty(&mut result.ty);
+        if let Some(result) = &mut ty.result {
+            self.expand_component_val_ty(result);
         }
     }
 
diff --git a/crates/wast/src/component/resolve.rs b/crates/wast/src/component/resolve.rs
index 5a61068c..aa1187fc 100644
--- a/crates/wast/src/component/resolve.rs
+++ b/crates/wast/src/component/resolve.rs
@@ -620,8 +620,8 @@ impl<'a> Resolver<'a> {
                     self.component_val_type(&mut param.ty)?;
                 }
 
-                for result in f.results.iter_mut() {
-                    self.component_val_type(&mut result.ty)?;
+                if let Some(result) = &mut f.result {
+                    self.component_val_type(result)?;
                 }
             }
             TypeDef::Component(c) => {
diff --git a/crates/wast/src/component/types.rs b/crates/wast/src/component/types.rs
index 23951f21..70fd05ca 100644
--- a/crates/wast/src/component/types.rs
+++ b/crates/wast/src/component/types.rs
@@ -728,9 +728,8 @@ pub struct ComponentFunctionType<'a> {
     /// The parameters of a function, optionally each having an identifier for
     /// name resolution and a name for the custom `name` section.
     pub params: Box<[ComponentFunctionParam<'a>]>,
-    /// The result of a function, optionally each having an identifier for
-    /// name resolution and a name for the custom `name` section.
-    pub results: Box<[ComponentFunctionResult<'a>]>,
+    /// The result of a function.
+    pub result: Option<ComponentValType<'a>>,
 }
 
 impl<'a> Parse<'a> for ComponentFunctionType<'a> {
@@ -740,14 +739,18 @@ impl<'a> Parse<'a> for ComponentFunctionType<'a> {
             params.push(parser.parens(|p| p.parse())?);
         }
 
-        let mut results: Vec<ComponentFunctionResult> = Vec::new();
-        while parser.peek2::<kw::result>()? {
-            results.push(parser.parens(|p| p.parse())?);
-        }
+        let result = if parser.peek2::<kw::result>()? {
+            Some(parser.parens(|p| {
+                p.parse::<kw::result>()?;
+                p.parse()
+            })?)
+        } else {
+            None
+        };
 
         Ok(Self {
             params: params.into(),
-            results: results.into(),
+            result,
         })
     }
 }
diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs
index 0f433b93..8a05ac69 100644
--- a/crates/wit-component/src/encoding.rs
+++ b/crates/wit-component/src/encoding.rs
@@ -84,8 +84,8 @@ use wasm_encoder::*;
 use wasmparser::Validator;
 use wit_parser::{
     abi::{AbiVariant, WasmSignature, WasmType},
-    Function, FunctionKind, InterfaceId, LiveTypes, Resolve, Results, Stability, Type, TypeDefKind,
-    TypeId, TypeOwner, WorldItem, WorldKey,
+    Function, FunctionKind, InterfaceId, LiveTypes, Resolve, Stability, Type, TypeDefKind, TypeId,
+    TypeOwner, WorldItem, WorldKey,
 };
 
 const INDIRECT_TABLE_NAME: &str = "$imports";
@@ -137,7 +137,7 @@ impl RequiredOptions {
             resolve,
             func.params.iter().map(|(_, t)| t),
         ));
-        ret.add_lower(TypeContents::for_types(resolve, func.results.iter_types()));
+        ret.add_lower(TypeContents::for_types(resolve, &func.result));
 
         // If anything is indirect then `memory` will be required to read the
         // indirect values.
@@ -158,7 +158,7 @@ impl RequiredOptions {
             resolve,
             func.params.iter().map(|(_, t)| t),
         ));
-        ret.add_lift(TypeContents::for_types(resolve, func.results.iter_types()));
+        ret.add_lift(TypeContents::for_types(resolve, &func.result));
 
         // If anything is indirect then `memory` will be required to read the
         // indirect values, but if the arguments are indirect then `realloc` is
@@ -277,7 +277,7 @@ bitflags::bitflags! {
 }
 
 impl TypeContents {
-    fn for_types<'a>(resolve: &Resolve, types: impl Iterator<Item = &'a Type>) -> Self {
+    fn for_types<'a>(resolve: &Resolve, types: impl IntoIterator<Item = &'a Type>) -> Self {
         let mut cur = TypeContents::empty();
         for ty in types {
             cur |= Self::for_type(resolve, ty);
@@ -1310,9 +1310,9 @@ impl<'a> EncodingState<'a> {
                                         .enumerate()
                                         .map(|(i, v)| (format!("a{i}"), v))
                                         .collect(),
-                                    results: match &results[..] {
-                                        [] => Results::Named(Vec::new()),
-                                        [ty] => Results::Anon(*ty),
+                                    result: match &results[..] {
+                                        [] => None,
+                                        [ty] => Some(*ty),
                                         _ => unreachable!(),
                                     },
                                     docs: Default::default(),
@@ -1721,15 +1721,9 @@ impl<'a> EncodingState<'a> {
             Import::ExportedTaskReturn(interface, function) => {
                 let mut encoder = self.root_export_type_encoder(*interface);
 
-                let result = match &function.results {
-                    Results::Named(rs) => {
-                        if rs.is_empty() {
-                            None
-                        } else {
-                            bail!("named results not supported for `task.return` intrinsic")
-                        }
-                    }
-                    Results::Anon(ty) => Some(encoder.encode_valtype(resolve, ty)?),
+                let result = match &function.result {
+                    Some(ty) => Some(encoder.encode_valtype(resolve, ty)?),
+                    None => None,
                 };
 
                 let index = self.component.task_return(result);
diff --git a/crates/wit-component/src/encoding/types.rs b/crates/wit-component/src/encoding/types.rs
index cdf2e893..9cee8e09 100644
--- a/crates/wit-component/src/encoding/types.rs
+++ b/crates/wit-component/src/encoding/types.rs
@@ -3,15 +3,15 @@ use anyhow::Result;
 use std::collections::HashMap;
 use wasm_encoder::*;
 use wit_parser::{
-    Enum, Flags, Function, Handle, InterfaceId, Params, Record, Resolve, Result_, Results, Tuple,
-    Type, TypeDefKind, TypeId, TypeOwner, Variant,
+    Enum, Flags, Function, Handle, InterfaceId, Record, Resolve, Result_, Tuple, Type, TypeDefKind,
+    TypeId, TypeOwner, Variant,
 };
 
 /// Represents a key type for interface function definitions.
 #[derive(Hash, PartialEq, Eq)]
 pub struct FunctionKey<'a> {
-    params: &'a Params,
-    results: &'a Results,
+    params: &'a [(String, Type)],
+    result: &'a Option<Type>,
 }
 
 /// Support for encoding a wit-parser type into a component.
@@ -59,7 +59,7 @@ pub trait ValtypeEncoder<'a> {
     fn encode_func_type(&mut self, resolve: &'a Resolve, func: &'a Function) -> Result<u32> {
         let key = FunctionKey {
             params: &func.params,
-            results: &func.results,
+            result: &func.result,
         };
         if let Some(index) = self.func_type_map().get(&key) {
             return Ok(*index);
@@ -68,23 +68,14 @@ pub trait ValtypeEncoder<'a> {
         // Encode all referenced parameter types from this function.
         let params: Vec<_> = self.encode_params(resolve, &func.params)?;
 
-        enum EncodedResults<'a> {
-            Named(Vec<(&'a str, ComponentValType)>),
-            Anon(ComponentValType),
-        }
-
-        let results = match &func.results {
-            Results::Named(rs) => EncodedResults::Named(self.encode_params(resolve, rs)?),
-            Results::Anon(ty) => EncodedResults::Anon(self.encode_valtype(resolve, ty)?),
-        };
+        let result = func
+            .result
+            .map(|ty| self.encode_valtype(resolve, &ty))
+            .transpose()?;
 
         // Encode the function type
         let (index, mut f) = self.define_function_type();
-        f.params(params);
-        match results {
-            EncodedResults::Named(rs) => f.results(rs),
-            EncodedResults::Anon(ty) => f.result(ty),
-        };
+        f.params(params).result(result);
         let prev = self.func_type_map().insert(key, index);
         assert!(prev.is_none());
         Ok(index)
@@ -93,7 +84,7 @@ pub trait ValtypeEncoder<'a> {
     fn encode_params(
         &mut self,
         resolve: &'a Resolve,
-        params: &'a Params,
+        params: &'a [(String, Type)],
     ) -> Result<Vec<(&'a str, ComponentValType)>> {
         params
             .iter()
diff --git a/crates/wit-component/src/printing.rs b/crates/wit-component/src/printing.rs
index 9c6e7165..3970214d 100644
--- a/crates/wit-component/src/printing.rs
+++ b/crates/wit-component/src/printing.rs
@@ -360,26 +360,9 @@ impl<O: Output> WitPrinter<O> {
             return Ok(());
         }
 
-        match &func.results {
-            Results::Named(rs) => match rs.len() {
-                0 => (),
-                _ => {
-                    self.output.str(" -> (");
-                    for (i, (name, ty)) in rs.iter().enumerate() {
-                        if i > 0 {
-                            self.output.str(", ");
-                        }
-                        self.print_name_param(name);
-                        self.output.str(": ");
-                        self.print_type_name(resolve, ty)?;
-                    }
-                    self.output.str(")");
-                }
-            },
-            Results::Anon(ty) => {
-                self.output.str(" -> ");
-                self.print_type_name(resolve, ty)?;
-            }
+        if let Some(ty) = &func.result {
+            self.output.str(" -> ");
+            self.print_type_name(resolve, ty)?;
         }
         Ok(())
     }
diff --git a/crates/wit-encoder/src/from_parser.rs b/crates/wit-encoder/src/from_parser.rs
index 32c97cc9..6e7e4302 100644
--- a/crates/wit-encoder/src/from_parser.rs
+++ b/crates/wit-encoder/src/from_parser.rs
@@ -1,7 +1,7 @@
 use crate::{
     Enum, Flags, Ident, Interface, InterfaceItem, Package, PackageName, Params, Record, Resource,
-    ResourceFunc, Result_, Results, StandaloneFunc, Tuple, Type, TypeDef, TypeDefKind, Variant,
-    World, WorldItem,
+    ResourceFunc, Result_, StandaloneFunc, Tuple, Type, TypeDef, TypeDefKind, Variant, World,
+    WorldItem,
 };
 use id_arena::Id;
 use wit_parser::PackageId;
@@ -425,7 +425,7 @@ impl<'a> Converter<'a> {
         }
 
         if with_returns {
-            method.set_results(self.convert_results(&func.results));
+            method.set_result(func.result.as_ref().map(|ty| self.convert_type(ty)));
         }
 
         Some(method)
@@ -440,14 +440,14 @@ impl<'a> Converter<'a> {
                 let mut output = StandaloneFunc::new(func.name.clone());
 
                 output.set_params(self.convert_params(&func.params));
-                output.set_results(self.convert_results(&func.results));
+                output.set_result(func.result.map(|ty| self.convert_type(&ty)));
 
                 Some(output)
             }
         }
     }
 
-    fn convert_params(&self, params: &wit_parser::Params) -> Params {
+    fn convert_params(&self, params: &[(String, wit_parser::Type)]) -> Params {
         let mut output = Params::empty();
         for (name, ty) in params.iter() {
             let name = name.to_string();
@@ -457,16 +457,6 @@ impl<'a> Converter<'a> {
         output
     }
 
-    fn convert_results(&self, results: &wit_parser::Results) -> Results {
-        match results {
-            wit_parser::Results::Named(named) => Results::named(named.iter().map(|(name, ty)| {
-                let ty = self.convert_type(ty);
-                (name.to_owned(), ty)
-            })),
-            wit_parser::Results::Anon(ty) => Results::Anon(self.convert_type(ty)),
-        }
-    }
-
     fn handle_to_type(&self, handle: &wit_parser::Handle) -> Type {
         let id = match handle {
             wit_parser::Handle::Own(id) => id,
diff --git a/crates/wit-encoder/src/function.rs b/crates/wit-encoder/src/function.rs
index a86d153b..b993f4f6 100644
--- a/crates/wit-encoder/src/function.rs
+++ b/crates/wit-encoder/src/function.rs
@@ -66,95 +66,13 @@ impl Params {
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
-pub enum Results {
-    Named(Params),
-    Anon(Type),
-}
-
-impl Display for Results {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            Results::Anon(type_) => type_.fmt(f)?,
-            Results::Named(vals) => {
-                if !vals.items.is_empty() {
-                    write!(f, "(")?;
-                    let mut peekable = vals.items.iter().peekable();
-                    while let Some((name, type_)) = peekable.next() {
-                        write!(f, "{}: {}", name, type_)?;
-                        if peekable.peek().is_some() {
-                            write!(f, ", ")?;
-                        }
-                    }
-                    write!(f, ")")?;
-                }
-            }
-        };
-        Ok(())
-    }
-}
-
-impl Default for Results {
-    fn default() -> Self {
-        Results::empty()
-    }
-}
-
-impl From<Type> for Results {
-    fn from(value: Type) -> Self {
-        Results::Anon(value)
-    }
-}
-
-impl<N> FromIterator<(N, Type)> for Results
-where
-    N: Into<Ident>,
-{
-    fn from_iter<T: IntoIterator<Item = (N, Type)>>(iter: T) -> Self {
-        Results::Named(Params::from_iter(iter))
-    }
-}
-
-impl Results {
-    // For the common case of an empty results list.
-    pub fn empty() -> Results {
-        Results::Named(Params::empty())
-    }
-
-    pub fn anon(type_: Type) -> Results {
-        Results::Anon(type_)
-    }
-
-    pub fn named(types: impl IntoIterator<Item = (impl Into<Ident>, Type)>) -> Results {
-        Results::Named(
-            types
-                .into_iter()
-                .map(|(name, ty)| (name.into(), ty))
-                .collect(),
-        )
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.len() == 0
-    }
-
-    pub fn len(&self) -> usize {
-        match self {
-            Results::Named(params) => params.items().len(),
-            Results::Anon(_) => 1,
-        }
-    }
-}
-
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
 pub struct StandaloneFunc {
     pub(crate) name: Ident,
     pub(crate) params: Params,
-    pub(crate) results: Results,
+    pub(crate) result: Option<Type>,
     pub(crate) docs: Option<Docs>,
 }
 
@@ -163,7 +81,7 @@ impl StandaloneFunc {
         Self {
             name: name.into(),
             params: Params::empty(),
-            results: Results::empty(),
+            result: None,
             docs: None,
         }
     }
@@ -192,16 +110,16 @@ impl StandaloneFunc {
         &mut self.params
     }
 
-    pub fn results(&self) -> &Results {
-        &self.results
+    pub fn result(&self) -> &Option<Type> {
+        &self.result
     }
 
-    pub fn set_results(&mut self, results: impl Into<Results>) {
-        self.results = results.into();
+    pub fn set_result(&mut self, result: Option<Type>) {
+        self.result = result;
     }
 
-    pub fn results_mut(&mut self) -> &mut Results {
-        &mut self.results
+    pub fn result_mut(&mut self) -> &mut Option<Type> {
+        &mut self.result
     }
 
     pub fn set_docs(&mut self, docs: Option<impl Into<Docs>>) {
@@ -212,14 +130,3 @@ impl StandaloneFunc {
         &self.docs
     }
 }
-
-#[cfg(test)]
-mod test {
-    use crate::Results;
-
-    #[test]
-    fn is_empty() {
-        let res = Results::empty();
-        assert!(res.is_empty());
-    }
-}
diff --git a/crates/wit-encoder/src/interface.rs b/crates/wit-encoder/src/interface.rs
index a64135be..3c5e2472 100644
--- a/crates/wit-encoder/src/interface.rs
+++ b/crates/wit-encoder/src/interface.rs
@@ -126,8 +126,8 @@ impl Render for InterfaceItems {
                         docs.render(f, opts)?;
                     }
                     write!(f, "{}{}: func({})", opts.spaces(), func.name, func.params,)?;
-                    if !func.results.is_empty() {
-                        write!(f, " -> {}", func.results)?;
+                    if let Some(ty) = &func.result {
+                        write!(f, " -> {ty}")?;
                     }
                     write!(f, ";\n")?;
                 }
diff --git a/crates/wit-encoder/src/resource.rs b/crates/wit-encoder/src/resource.rs
index cab2ff6a..6d47e89c 100644
--- a/crates/wit-encoder/src/resource.rs
+++ b/crates/wit-encoder/src/resource.rs
@@ -1,4 +1,4 @@
-use crate::{ident::Ident, Docs, Params, Results};
+use crate::{ident::Ident, Docs, Params, Type};
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -38,15 +38,15 @@ pub struct ResourceFunc {
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
 pub enum ResourceFuncKind {
-    Method(Ident, Results),
-    Static(Ident, Results),
+    Method(Ident, Option<Type>),
+    Static(Ident, Option<Type>),
     Constructor,
 }
 
 impl ResourceFunc {
     pub fn method(name: impl Into<Ident>) -> Self {
         Self {
-            kind: ResourceFuncKind::Method(name.into(), Results::empty()),
+            kind: ResourceFuncKind::Method(name.into(), None),
             params: Params::empty(),
             docs: None,
         }
@@ -54,7 +54,7 @@ impl ResourceFunc {
 
     pub fn static_(name: impl Into<Ident>) -> Self {
         Self {
-            kind: ResourceFuncKind::Static(name.into(), Results::empty()),
+            kind: ResourceFuncKind::Static(name.into(), None),
             params: Params::empty(),
             docs: None,
         }
@@ -96,30 +96,30 @@ impl ResourceFunc {
         &mut self.params
     }
 
-    pub fn set_results(&mut self, results: impl Into<Results>) {
+    pub fn set_result(&mut self, results: Option<Type>) {
         match &self.kind {
             ResourceFuncKind::Method(name, _) => {
-                self.kind = ResourceFuncKind::Method(name.clone(), results.into())
+                self.kind = ResourceFuncKind::Method(name.clone(), results)
             }
             ResourceFuncKind::Static(name, _) => {
-                self.kind = ResourceFuncKind::Static(name.clone(), results.into())
+                self.kind = ResourceFuncKind::Static(name.clone(), results)
             }
             ResourceFuncKind::Constructor => panic!("constructors cannot have results"),
         }
     }
 
-    pub fn results(&self) -> Option<&Results> {
+    pub fn result(&self) -> Option<&Option<Type>> {
         match &self.kind {
-            ResourceFuncKind::Method(_, results) => Some(results),
-            ResourceFuncKind::Static(_, results) => Some(results),
+            ResourceFuncKind::Method(_, result) => Some(result),
+            ResourceFuncKind::Static(_, result) => Some(result),
             ResourceFuncKind::Constructor => None,
         }
     }
 
-    pub fn results_mut(&mut self) -> Option<&mut Results> {
+    pub fn result_mut(&mut self) -> Option<&mut Option<Type>> {
         match &mut self.kind {
-            ResourceFuncKind::Method(_, results) => Some(results),
-            ResourceFuncKind::Static(_, results) => Some(results),
+            ResourceFuncKind::Method(_, result) => Some(result),
+            ResourceFuncKind::Static(_, result) => Some(result),
             ResourceFuncKind::Constructor => None,
         }
     }
diff --git a/crates/wit-encoder/src/ty.rs b/crates/wit-encoder/src/ty.rs
index afe4891a..b82860ea 100644
--- a/crates/wit-encoder/src/ty.rs
+++ b/crates/wit-encoder/src/ty.rs
@@ -402,17 +402,17 @@ impl Render for TypeDef {
                         docs.render(f, &opts)?;
                     }
                     match &func.kind {
-                        crate::ResourceFuncKind::Method(name, results) => {
+                        crate::ResourceFuncKind::Method(name, result) => {
                             write!(f, "{}{}: func({})", opts.spaces(), name, func.params)?;
-                            if !results.is_empty() {
-                                write!(f, " -> {}", results)?;
+                            if let Some(ty) = result {
+                                write!(f, " -> {ty}")?;
                             }
                             write!(f, ";\n")?;
                         }
-                        crate::ResourceFuncKind::Static(name, results) => {
+                        crate::ResourceFuncKind::Static(name, result) => {
                             write!(f, "{}{}: static func({})", opts.spaces(), name, func.params)?;
-                            if !results.is_empty() {
-                                write!(f, " -> {}", results)?;
+                            if let Some(ty) = result {
+                                write!(f, " -> {ty}")?;
                             }
                             write!(f, ";\n")?;
                         }
diff --git a/crates/wit-encoder/src/world.rs b/crates/wit-encoder/src/world.rs
index 9aebb00d..d712061f 100644
--- a/crates/wit-encoder/src/world.rs
+++ b/crates/wit-encoder/src/world.rs
@@ -127,8 +127,8 @@ impl Render for World {
             func: &StandaloneFunc,
         ) -> fmt::Result {
             write!(f, "{}: func({})", func.name, func.params)?;
-            if !func.results.is_empty() {
-                write!(f, " -> {}", func.results)?;
+            if let Some(ty) = &func.result {
+                write!(f, " -> {ty}")?;
             }
             write!(f, ";\n")?;
             Ok(())
diff --git a/crates/wit-parser/src/abi.rs b/crates/wit-parser/src/abi.rs
index 35cf94d8..4af7dffa 100644
--- a/crates/wit-parser/src/abi.rs
+++ b/crates/wit-parser/src/abi.rs
@@ -202,7 +202,7 @@ impl Resolve {
         }
 
         let mut results = Vec::new();
-        for ty in func.results.iter_types() {
+        if let Some(ty) = &func.result {
             self.push_flat(ty, &mut results)
         }
 
diff --git a/crates/wit-parser/src/ast.rs b/crates/wit-parser/src/ast.rs
index f7091fdf..3e2d391a 100644
--- a/crates/wit-parser/src/ast.rs
+++ b/crates/wit-parser/src/ast.rs
@@ -819,7 +819,7 @@ impl<'a> ResourceFunc<'a> {
                     func: Func {
                         span,
                         params,
-                        results: ResultList::Named(Vec::new()),
+                        result: None,
                     },
                 }))
             }
@@ -934,15 +934,10 @@ struct NamedFunc<'a> {
 
 type ParamList<'a> = Vec<(Id<'a>, Type<'a>)>;
 
-enum ResultList<'a> {
-    Named(ParamList<'a>),
-    Anon(Type<'a>),
-}
-
 struct Func<'a> {
     span: Span,
     params: ParamList<'a>,
-    results: ResultList<'a>,
+    result: Option<Type<'a>>,
 }
 
 impl<'a> Func<'a> {
@@ -961,23 +956,16 @@ impl<'a> Func<'a> {
 
         let span = tokens.expect(Token::Func)?;
         let params = parse_params(tokens, true)?;
-        let results = if tokens.eat(Token::RArrow)? {
-            // If we eat a '(', parse the remainder of the named
-            // result types. Otherwise parse a single anonymous type.
-            if tokens.eat(Token::LeftParen)? {
-                let results = parse_params(tokens, false)?;
-                ResultList::Named(results)
-            } else {
-                let ty = Type::parse(tokens)?;
-                ResultList::Anon(ty)
-            }
+        let result = if tokens.eat(Token::RArrow)? {
+            let ty = Type::parse(tokens)?;
+            Some(ty)
         } else {
-            ResultList::Named(Vec::new())
+            None
         };
         Ok(Func {
             span,
             params,
-            results,
+            result,
         })
     }
 }
diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs
index a1392d6a..59fdba0f 100644
--- a/crates/wit-parser/src/ast/resolve.rs
+++ b/crates/wit-parser/src/ast/resolve.rs
@@ -1,4 +1,4 @@
-use super::{ParamList, ResultList, WorldOrInterface};
+use super::{ParamList, WorldOrInterface};
 use crate::ast::toposort::toposort;
 use crate::*;
 use anyhow::bail;
@@ -1047,14 +1047,14 @@ impl<'a> Resolver<'a> {
         let docs = self.docs(docs);
         let stability = self.stability(attrs)?;
         let params = self.resolve_params(&func.params, &kind, func.span)?;
-        let results = self.resolve_results(&func.results, &kind, func.span)?;
+        let result = self.resolve_result(&func.result, &kind, func.span)?;
         Ok(Function {
             docs,
             stability,
             name: name.to_string(),
             kind,
             params,
-            results,
+            result,
         })
     }
 
@@ -1542,7 +1542,7 @@ impl<'a> Resolver<'a> {
         params: &ParamList<'_>,
         kind: &FunctionKind,
         span: Span,
-    ) -> Result<Params> {
+    ) -> Result<Vec<(String, Type)>> {
         let mut ret = IndexMap::new();
         match *kind {
             // These kinds of methods don't have any adjustments to the
@@ -1583,25 +1583,19 @@ impl<'a> Resolver<'a> {
         Ok(ret.into_iter().collect())
     }
 
-    fn resolve_results(
+    fn resolve_result(
         &mut self,
-        results: &ResultList<'_>,
+        result: &Option<ast::Type<'_>>,
         kind: &FunctionKind,
-        span: Span,
-    ) -> Result<Results> {
+        _span: Span,
+    ) -> Result<Option<Type>> {
         match *kind {
             // These kinds of methods don't have any adjustments to the return
             // values, so plumb them through as-is.
             FunctionKind::Freestanding | FunctionKind::Method(_) | FunctionKind::Static(_) => {
-                match results {
-                    ResultList::Named(rs) => Ok(Results::Named(self.resolve_params(
-                        rs,
-                        &FunctionKind::Freestanding,
-                        span,
-                    )?)),
-                    ResultList::Anon(ty) => {
-                        Ok(Results::Anon(self.resolve_type(ty, &Stability::Unknown)?))
-                    }
+                match result {
+                    Some(ty) => Ok(Some(self.resolve_type(ty, &Stability::Unknown)?)),
+                    None => Ok(None),
                 }
             }
 
@@ -1609,11 +1603,8 @@ impl<'a> Resolver<'a> {
             // automatically translated as a single return type of the type that
             // it's a constructor for.
             FunctionKind::Constructor(id) => {
-                match results {
-                    ResultList::Named(rs) => assert!(rs.is_empty()),
-                    ResultList::Anon(_) => unreachable!(),
-                }
-                Ok(Results::Anon(Type::Id(id)))
+                assert!(result.is_none());
+                Ok(Some(Type::Id(id)))
             }
         }
     }
diff --git a/crates/wit-parser/src/decoding.rs b/crates/wit-parser/src/decoding.rs
index 2cc0b406..64a5a690 100644
--- a/crates/wit-parser/src/decoding.rs
+++ b/crates/wit-parser/src/decoding.rs
@@ -1187,24 +1187,12 @@ impl WitPackageDecoder<'_> {
             .map(|(name, ty)| Ok((name.to_string(), self.convert_valtype(ty)?)))
             .collect::<Result<Vec<_>>>()
             .context("failed to convert params")?;
-        let results = if ty.results.len() == 1 && ty.results[0].0.is_none() {
-            Results::Anon(
-                self.convert_valtype(&ty.results[0].1)
+        let result = match &ty.result {
+            Some(ty) => Some(
+                self.convert_valtype(ty)
                     .context("failed to convert anonymous result type")?,
-            )
-        } else {
-            Results::Named(
-                ty.results
-                    .iter()
-                    .map(|(name, ty)| {
-                        Ok((
-                            name.as_ref().unwrap().to_string(),
-                            self.convert_valtype(ty)?,
-                        ))
-                    })
-                    .collect::<Result<Vec<_>>>()
-                    .context("failed to convert named result types")?,
-            )
+            ),
+            None => None,
         };
         Ok(Function {
             docs: Default::default(),
@@ -1234,7 +1222,7 @@ impl WitPackageDecoder<'_> {
             // name.
             name: name.to_string(),
             params,
-            results,
+            result,
         })
     }
 
diff --git a/crates/wit-parser/src/lib.rs b/crates/wit-parser/src/lib.rs
index 3e11bba8..dc945735 100644
--- a/crates/wit-parser/src/lib.rs
+++ b/crates/wit-parser/src/lib.rs
@@ -795,85 +795,15 @@ impl Docs {
     }
 }
 
-pub type Params = Vec<(String, Type)>;
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-#[cfg_attr(feature = "serde", derive(Serialize))]
-#[cfg_attr(feature = "serde", serde(untagged))]
-pub enum Results {
-    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_params"))]
-    Named(Params),
-    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_anon_result"))]
-    Anon(Type),
-}
-
-pub enum ResultsTypeIter<'a> {
-    Named(std::slice::Iter<'a, (String, Type)>),
-    Anon(std::iter::Once<&'a Type>),
-}
-
-impl<'a> Iterator for ResultsTypeIter<'a> {
-    type Item = &'a Type;
-
-    fn next(&mut self) -> Option<&'a Type> {
-        match self {
-            ResultsTypeIter::Named(ps) => ps.next().map(|p| &p.1),
-            ResultsTypeIter::Anon(ty) => ty.next(),
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        match self {
-            ResultsTypeIter::Named(ps) => ps.size_hint(),
-            ResultsTypeIter::Anon(ty) => ty.size_hint(),
-        }
-    }
-}
-
-impl<'a> ExactSizeIterator for ResultsTypeIter<'a> {}
-
-impl Results {
-    // For the common case of an empty results list.
-    pub fn empty() -> Results {
-        Results::Named(Vec::new())
-    }
-
-    pub fn len(&self) -> usize {
-        match self {
-            Results::Named(params) => params.len(),
-            Results::Anon(_) => 1,
-        }
-    }
-
-    pub fn throws<'a>(&self, resolve: &'a Resolve) -> Option<(Option<&'a Type>, Option<&'a Type>)> {
-        if self.len() != 1 {
-            return None;
-        }
-        match self.iter_types().next().unwrap() {
-            Type::Id(id) => match &resolve.types[*id].kind {
-                TypeDefKind::Result(r) => Some((r.ok.as_ref(), r.err.as_ref())),
-                _ => None,
-            },
-            _ => None,
-        }
-    }
-
-    pub fn iter_types(&self) -> ResultsTypeIter {
-        match self {
-            Results::Named(ps) => ResultsTypeIter::Named(ps.iter()),
-            Results::Anon(ty) => ResultsTypeIter::Anon(std::iter::once(ty)),
-        }
-    }
-}
-
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[cfg_attr(feature = "serde", derive(Serialize))]
 pub struct Function {
     pub name: String,
     pub kind: FunctionKind,
     #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_params"))]
-    pub params: Params,
-    pub results: Results,
+    pub params: Vec<(String, Type)>,
+    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
+    pub result: Option<Type>,
     #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
     pub docs: Docs,
     /// Stability attribute for this function.
@@ -1036,10 +966,7 @@ impl Function {
     /// Note that this iterator is not transitive, it only iterates over the
     /// direct references to types that this function has.
     pub fn parameter_and_result_types(&self) -> impl Iterator<Item = Type> + '_ {
-        self.params
-            .iter()
-            .map(|(_, t)| *t)
-            .chain(self.results.iter_types().copied())
+        self.params.iter().map(|(_, t)| *t).chain(self.result)
     }
 
     /// Gets the core export name for this function.
@@ -1087,8 +1014,8 @@ impl Function {
         for (_, ty) in self.params.iter() {
             find_futures_and_streams(resolve, *ty, &mut results);
         }
-        for ty in self.results.iter_types() {
-            find_futures_and_streams(resolve, *ty, &mut results);
+        if let Some(ty) = self.result {
+            find_futures_and_streams(resolve, ty, &mut results);
         }
         results
     }
@@ -1257,7 +1184,7 @@ mod test {
             name: "foo".into(),
             kind: FunctionKind::Freestanding,
             params: vec![("p1".into(), Type::Id(t1)), ("p2".into(), Type::U32)],
-            results: Results::Anon(Type::Id(t2)),
+            result: Some(Type::Id(t2)),
             docs: Docs::default(),
             stability: Stability::Unknown,
         }
diff --git a/crates/wit-parser/src/live.rs b/crates/wit-parser/src/live.rs
index 2027bd1b..d7c04306 100644
--- a/crates/wit-parser/src/live.rs
+++ b/crates/wit-parser/src/live.rs
@@ -112,7 +112,7 @@ pub trait TypeIdVisitor {
         for (_, ty) in func.params.iter() {
             self.visit_type(resolve, ty);
         }
-        for ty in func.results.iter_types() {
+        if let Some(ty) = &func.result {
             self.visit_type(resolve, ty);
         }
     }
diff --git a/crates/wit-parser/src/resolve.rs b/crates/wit-parser/src/resolve.rs
index 060dfb11..8646f77a 100644
--- a/crates/wit-parser/src/resolve.rs
+++ b/crates/wit-parser/src/resolve.rs
@@ -18,9 +18,9 @@ use crate::ast::{parse_use_path, ParsedUsePath};
 use crate::serde_::{serialize_arena, serialize_id_map};
 use crate::{
     AstItem, Docs, Error, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
-    InterfaceSpan, LiftLowerAbi, ManglingAndAbi, PackageName, PackageNotFoundError, Results,
-    SourceMap, Stability, Type, TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner,
-    UnresolvedPackage, UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey, WorldSpan,
+    InterfaceSpan, LiftLowerAbi, ManglingAndAbi, PackageName, PackageNotFoundError, SourceMap,
+    Stability, Type, TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage,
+    UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey, WorldSpan,
 };
 
 mod clone;
@@ -3212,30 +3212,24 @@ impl Remap {
         for (_, ty) in func.params.iter_mut() {
             self.update_ty(resolve, ty, span)?;
         }
-        match &mut func.results {
-            Results::Named(named) => {
-                for (_, ty) in named.iter_mut() {
-                    self.update_ty(resolve, ty, span)?;
-                }
-            }
-            Results::Anon(ty) => self.update_ty(resolve, ty, span)?,
+        if let Some(ty) = &mut func.result {
+            self.update_ty(resolve, ty, span)?;
         }
 
-        for ty in func.results.iter_types() {
-            if !self.type_has_borrow(resolve, ty) {
-                continue;
-            }
-            match span {
-                Some(span) => {
-                    bail!(Error::new(
-                        span,
-                        format!(
-                            "function returns a type which contains \
-                             a `borrow<T>` which is not supported"
-                        )
-                    ))
+        if let Some(ty) = &func.result {
+            if self.type_has_borrow(resolve, ty) {
+                match span {
+                    Some(span) => {
+                        bail!(Error::new(
+                            span,
+                            format!(
+                                "function returns a type which contains \
+                                 a `borrow<T>` which is not supported"
+                            )
+                        ))
+                    }
+                    None => unreachable!(),
                 }
-                None => unreachable!(),
             }
         }
 
@@ -3699,16 +3693,13 @@ impl<'a> MergeMap<'a> {
             self.build_type(from_ty, into_ty)
                 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
         }
-        if from_func.results.len() != into_func.results.len() {
-            bail!("different number of function results");
-        }
-        for (from_ty, into_ty) in from_func
-            .results
-            .iter_types()
-            .zip(into_func.results.iter_types())
-        {
-            self.build_type(from_ty, into_ty)
-                .context("different function result types")?;
+        match (&from_func.result, &into_func.result) {
+            (Some(from_ty), Some(into_ty)) => {
+                self.build_type(from_ty, into_ty)
+                    .context("different function result types")?;
+            }
+            (None, None) => {}
+            (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
         }
         Ok(())
     }
diff --git a/crates/wit-parser/src/resolve/clone.rs b/crates/wit-parser/src/resolve/clone.rs
index 1f7dc543..650a7047 100644
--- a/crates/wit-parser/src/resolve/clone.rs
+++ b/crates/wit-parser/src/resolve/clone.rs
@@ -164,13 +164,8 @@ impl<'a> Cloner<'a> {
         for (_, ty) in func.params.iter_mut() {
             self.ty(ty);
         }
-        match &mut func.results {
-            Results::Named(named) => {
-                for (_, ty) in named {
-                    self.ty(ty);
-                }
-            }
-            Results::Anon(ty) => self.ty(ty),
+        if let Some(ty) = &mut func.result {
+            self.ty(ty);
         }
     }
 
diff --git a/crates/wit-parser/src/serde_.rs b/crates/wit-parser/src/serde_.rs
index 48e7f8ea..d7ed36b1 100644
--- a/crates/wit-parser/src/serde_.rs
+++ b/crates/wit-parser/src/serde_.rs
@@ -1,4 +1,4 @@
-use crate::{Params, Type};
+use crate::Type;
 use id_arena::{Arena, Id};
 use indexmap::IndexMap;
 use semver::Version;
@@ -77,15 +77,7 @@ impl Serialize for Type {
     }
 }
 
-pub fn serialize_anon_result<S>(typ: &Type, serializer: S) -> Result<S::Ok, S::Error>
-where
-    S: Serializer,
-{
-    let params: Params = vec![(String::default(), *typ)];
-    serialize_params(&params, serializer)
-}
-
-pub fn serialize_params<S>(params: &Params, serializer: S) -> Result<S::Ok, S::Error>
+pub fn serialize_params<S>(params: &[(String, Type)], serializer: S) -> Result<S::Ok, S::Error>
 where
     S: Serializer,
 {
diff --git a/src/bin/wasm-tools/metadata.rs b/src/bin/wasm-tools/metadata.rs
index c45124ec..cfa83536 100644
--- a/src/bin/wasm-tools/metadata.rs
+++ b/src/bin/wasm-tools/metadata.rs
@@ -99,7 +99,7 @@ fn fmt_payload(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
         .set_header(vec!["KIND", "VALUE"]);
     let Metadata {
         name,
-        author,
+        authors,
         description,
         producers,
         licenses,
@@ -130,8 +130,8 @@ fn fmt_payload(payload: &Payload, f: &mut Box<dyn WriteColor>) -> Result<()> {
     if let Some(licenses) = licenses {
         table.add_row(vec!["licenses", &licenses.to_string()]);
     }
-    if let Some(author) = author {
-        table.add_row(vec!["author", &author.to_string()]);
+    if let Some(authors) = authors {
+        table.add_row(vec!["authors", &authors.to_string()]);
     }
     if let Some(source) = source {
         table.add_row(vec!["source", &source.to_string()]);


Test patch:
diff --git a/crates/wasm-metadata/tests/component.rs b/crates/wasm-metadata/tests/component.rs
index 8ee2b4ef..b84a82c1 100644
--- a/crates/wasm-metadata/tests/component.rs
+++ b/crates/wasm-metadata/tests/component.rs
@@ -11,7 +11,7 @@ fn add_to_empty_component() {
         language: vec![("bar".to_owned(), "1.0".to_owned())],
         processed_by: vec![("baz".to_owned(), "1.0".to_owned())],
         sdk: vec![],
-        author: Some(Author::new("Chashu Cat")),
+        authors: Some(Authors::new("Chashu Cat")),
         description: Some(Description::new("Chashu likes tuna")),
         licenses: Some(
             Licenses::new("Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT").unwrap(),
@@ -30,7 +30,7 @@ fn add_to_empty_component() {
                 Metadata {
                     name,
                     producers,
-                    author,
+                    authors: author,
                     description,
                     licenses,
                     source,
@@ -52,7 +52,7 @@ fn add_to_empty_component() {
                 "1.0"
             );
 
-            assert_eq!(author.unwrap(), Author::new("Chashu Cat"));
+            assert_eq!(author.unwrap(), Authors::new("Chashu Cat"));
             assert_eq!(description.unwrap(), Description::new("Chashu likes tuna"));
             assert_eq!(
                 licenses.unwrap(),
@@ -73,7 +73,7 @@ fn add_to_empty_component() {
             assert_eq!(version.unwrap(), Version::new("1.0.0"));
 
             assert_eq!(range.start, 0);
-            assert_eq!(range.end, 374);
+            assert_eq!(range.end, 375);
         }
         _ => panic!("metadata should be component"),
     }
@@ -88,7 +88,7 @@ fn add_to_nested_component() {
         language: vec![("bar".to_owned(), "1.0".to_owned())],
         processed_by: vec![("baz".to_owned(), "1.0".to_owned())],
         sdk: vec![],
-        author: Some(Author::new("Chashu Cat")),
+        authors: Some(Authors::new("Chashu Cat")),
         description: Some(Description::new("Chashu likes tuna")),
         licenses: Some(
             Licenses::new("Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT").unwrap(),
@@ -137,7 +137,7 @@ fn add_to_nested_component() {
                 Payload::Module(Metadata {
                     name,
                     producers,
-                    author,
+                    authors: author,
                     licenses,
                     source,
                     range,
@@ -157,7 +157,7 @@ fn add_to_nested_component() {
                         "1.0"
                     );
 
-                    assert_eq!(author, &Some(Author::new("Chashu Cat")));
+                    assert_eq!(author, &Some(Authors::new("Chashu Cat")));
                     assert_eq!(description, &Some(Description::new("Chashu likes tuna")));
                     assert_eq!(
                         licenses,
@@ -186,7 +186,7 @@ fn add_to_nested_component() {
                     assert_eq!(version, &Some(Version::new("1.0.0")));
 
                     assert_eq!(range.start, 11);
-                    assert_eq!(range.end, 375);
+                    assert_eq!(range.end, 376);
                 }
                 _ => panic!("child is a module"),
             }
diff --git a/crates/wasm-metadata/tests/module.rs b/crates/wasm-metadata/tests/module.rs
index 987cda98..abac28ed 100644
--- a/crates/wasm-metadata/tests/module.rs
+++ b/crates/wasm-metadata/tests/module.rs
@@ -11,7 +11,7 @@ fn add_to_empty_module() {
         language: vec![("bar".to_owned(), "1.0".to_owned())],
         processed_by: vec![("baz".to_owned(), "1.0".to_owned())],
         sdk: vec![],
-        author: Some(Author::new("Chashu Cat")),
+        authors: Some(Authors::new("Chashu Cat")),
         description: Some(Description::new("Chashu likes tuna")),
         licenses: Some(
             Licenses::new("Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT").unwrap(),
@@ -27,7 +27,7 @@ fn add_to_empty_module() {
         Payload::Module(Metadata {
             name,
             producers,
-            author,
+            authors: author,
             licenses,
             source,
             range,
@@ -47,7 +47,7 @@ fn add_to_empty_module() {
                 "1.0"
             );
 
-            assert_eq!(author.unwrap(), Author::new("Chashu Cat"));
+            assert_eq!(author.unwrap(), Authors::new("Chashu Cat"));
             assert_eq!(description.unwrap(), Description::new("Chashu likes tuna"));
             assert_eq!(
                 licenses.unwrap(),
@@ -68,7 +68,7 @@ fn add_to_empty_module() {
             assert_eq!(version.unwrap(), Version::new("1.0.0"));
 
             assert_eq!(range.start, 0);
-            assert_eq!(range.end, 364);
+            assert_eq!(range.end, 365);
         }
         _ => panic!("metadata should be module"),
     }
diff --git a/crates/wit-component/tests/interfaces/single-named-result.wit b/crates/wit-component/tests/interfaces/single-named-result.wit
deleted file mode 100644
index 980b766b..00000000
--- a/crates/wit-component/tests/interfaces/single-named-result.wit
+++ /dev/null
@@ -1,5 +0,0 @@
-package foo:foo;
-
-interface foo {
-  a: func() -> (a: u32);
-}
diff --git a/crates/wit-component/tests/interfaces/single-named-result.wit.print b/crates/wit-component/tests/interfaces/single-named-result.wit.print
deleted file mode 100644
index 73b149bb..00000000
--- a/crates/wit-component/tests/interfaces/single-named-result.wit.print
+++ /dev/null
@@ -1,6 +0,0 @@
-package foo:foo;
-
-interface foo {
-  a: func() -> (a: u32);
-}
-
diff --git a/crates/wit-encoder/tests/functions.rs b/crates/wit-encoder/tests/functions.rs
index 53cf4751..2c7026eb 100644
--- a/crates/wit-encoder/tests/functions.rs
+++ b/crates/wit-encoder/tests/functions.rs
@@ -1,7 +1,5 @@
 use pretty_assertions::assert_eq;
-use wit_encoder::{
-    Interface, Package, PackageName, Params, Result_, Results, StandaloneFunc, Type,
-};
+use wit_encoder::{Interface, Package, PackageName, Params, Result_, StandaloneFunc, Type};
 
 const PACKAGE: &str = indoc::indoc! {"
     package foo:functions;
@@ -13,8 +11,6 @@ const PACKAGE: &str = indoc::indoc! {"
       f6: func() -> tuple<u32, u32>;
       f7: func(a: f32, b: f32) -> tuple<u32, u32>;
       f8: func(a: option<u32>) -> result<u32, f32>;
-      f9: func() -> (u: u32, f: f32);
-      f10: func() -> (u: u32);
       f11: func() -> result<f32>;
       f12: func() -> result<_, f32>;
       f13: func() -> result;
@@ -36,49 +32,39 @@ fn concrete_types() {
         });
         interface.function({
             let mut func = StandaloneFunc::new("f4");
-            func.set_results(Results::anon(Type::U32));
+            func.set_result(Some(Type::U32));
             func
         });
         interface.function({
             let mut func = StandaloneFunc::new("f6");
-            func.set_results(Results::anon(Type::tuple(vec![Type::U32, Type::U32])));
+            func.set_result(Some(Type::tuple(vec![Type::U32, Type::U32])));
             func
         });
         interface.function({
             let mut func = StandaloneFunc::new("f7");
             func.set_params(Params::from_iter([("a", Type::F32), ("b", Type::F32)]));
-            func.set_results(Type::tuple(vec![Type::U32, Type::U32]));
+            func.set_result(Some(Type::tuple(vec![Type::U32, Type::U32])));
             func
         });
         interface.function({
             let mut func = StandaloneFunc::new("f8");
             func.set_params(Params::from_iter([("a", Type::option(Type::U32))]));
-            func.set_results(Type::result(Result_::both(Type::U32, Type::F32)));
-            func
-        });
-        interface.function({
-            let mut func = StandaloneFunc::new("f9");
-            func.set_results(Results::named(vec![("u", Type::U32), ("f", Type::F32)]));
-            func
-        });
-        interface.function({
-            let mut func = StandaloneFunc::new("f10");
-            func.set_results(Results::named(vec![("u", Type::U32)]));
+            func.set_result(Some(Type::result(Result_::both(Type::U32, Type::F32))));
             func
         });
         interface.function({
             let mut func = StandaloneFunc::new("f11");
-            func.set_results(Type::result(Result_::ok(Type::F32)));
+            func.set_result(Some(Result_::ok(Type::F32).into()));
             func
         });
         interface.function({
             let mut func = StandaloneFunc::new("f12");
-            func.set_results(Type::result(Result_::err(Type::F32)));
+            func.set_result(Some(Result_::err(Type::F32).into()));
             func
         });
         interface.function({
             let mut func = StandaloneFunc::new("f13");
-            func.set_results(Type::result(Result_::empty()));
+            func.set_result(Some(Result_::empty().into()));
             func
         });
         interface
diff --git a/crates/wit-encoder/tests/type_defs.rs b/crates/wit-encoder/tests/type_defs.rs
index 5e0f2820..db42ca02 100644
--- a/crates/wit-encoder/tests/type_defs.rs
+++ b/crates/wit-encoder/tests/type_defs.rs
@@ -1,6 +1,6 @@
 use pretty_assertions::assert_eq;
 use wit_encoder::{
-    Field, Flag, Params, ResourceFunc, Result_, Results, Type, TypeDef, TypeDefKind, VariantCase,
+    Field, Flag, Params, ResourceFunc, Result_, Type, TypeDef, TypeDefKind, VariantCase,
 };
 
 const PACKAGE: &str = indoc::indoc! {"
@@ -232,7 +232,7 @@ fn types() {
                 },
                 {
                     let mut func = ResourceFunc::method("get-a");
-                    func.set_results(Results::anon(Type::U32));
+                    func.set_result(Some(Type::U32));
                     func.set_docs(Some("get a"));
                     func
                 },
diff --git a/crates/wit-encoder/tests/world.rs b/crates/wit-encoder/tests/world.rs
index ca629059..f96f55b4 100644
--- a/crates/wit-encoder/tests/world.rs
+++ b/crates/wit-encoder/tests/world.rs
@@ -40,7 +40,7 @@ fn worlds() {
         });
         world.function_export({
             let mut func = StandaloneFunc::new("scan");
-            func.set_results(Type::list(Type::U8));
+            func.set_result(Some(Type::list(Type::U8)));
             func.set_docs(Some("scan stuff"));
             func
         });
diff --git a/crates/wit-parser/tests/ui/error-context.wit.json b/crates/wit-parser/tests/ui/error-context.wit.json
index 259755e7..555a2543 100644
--- a/crates/wit-parser/tests/ui/error-context.wit.json
+++ b/crates/wit-parser/tests/ui/error-context.wit.json
@@ -20,11 +20,7 @@
               "type": 0
             }
           ],
-          "results": [
-            {
-              "type": 2
-            }
-          ]
+          "result": 2
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/feature-gates.wit.json b/crates/wit-parser/tests/ui/feature-gates.wit.json
index 9cdb44c5..e959720d 100644
--- a/crates/wit-parser/tests/ui/feature-gates.wit.json
+++ b/crates/wit-parser/tests/ui/feature-gates.wit.json
@@ -71,7 +71,6 @@
           "name": "ungated",
           "kind": "freestanding",
           "params": [],
-          "results": [],
           "stability": {
             "unstable": {
               "feature": "active"
@@ -149,11 +148,7 @@
             "constructor": 4
           },
           "params": [],
-          "results": [
-            {
-              "type": 6
-            }
-          ],
+          "result": 6,
           "stability": {
             "unstable": {
               "feature": "active"
@@ -166,7 +161,6 @@
             "static": 4
           },
           "params": [],
-          "results": [],
           "stability": {
             "unstable": {
               "feature": "active"
@@ -184,7 +178,6 @@
               "type": 5
             }
           ],
-          "results": [],
           "stability": {
             "unstable": {
               "feature": "active"
diff --git a/crates/wit-parser/tests/ui/feature-types.wit.json b/crates/wit-parser/tests/ui/feature-types.wit.json
index e8e5263a..929b3982 100644
--- a/crates/wit-parser/tests/ui/feature-types.wit.json
+++ b/crates/wit-parser/tests/ui/feature-types.wit.json
@@ -16,11 +16,7 @@
               "type": 0
             }
           ],
-          "results": [
-            {
-              "type": 1
-            }
-          ]
+          "result": 1
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/functions.wit b/crates/wit-parser/tests/ui/functions.wit
index e04025d5..efdb81f3 100644
--- a/crates/wit-parser/tests/ui/functions.wit
+++ b/crates/wit-parser/tests/ui/functions.wit
@@ -8,7 +8,4 @@ interface functions {
   f6: func() -> tuple<u32, u32>;
   f7: func(a: f32, b: f32) -> tuple<u32, u32>;
   f8: func(a: option<u32>) -> result<u32, f32>;
-  f9: func() -> (u: u32, f: f32);
-  f10: func() -> (u: u32);
-  f11: func() -> ();
 }
diff --git a/crates/wit-parser/tests/ui/functions.wit.json b/crates/wit-parser/tests/ui/functions.wit.json
index 902fe357..b6eb38fd 100644
--- a/crates/wit-parser/tests/ui/functions.wit.json
+++ b/crates/wit-parser/tests/ui/functions.wit.json
@@ -8,8 +8,7 @@
         "f1": {
           "name": "f1",
           "kind": "freestanding",
-          "params": [],
-          "results": []
+          "params": []
         },
         "f2": {
           "name": "f2",
@@ -19,8 +18,7 @@
               "name": "a",
               "type": "u32"
             }
-          ],
-          "results": []
+          ]
         },
         "f3": {
           "name": "f3",
@@ -30,28 +28,19 @@
               "name": "a",
               "type": "u32"
             }
-          ],
-          "results": []
+          ]
         },
         "f4": {
           "name": "f4",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": "u32"
-            }
-          ]
+          "result": "u32"
         },
         "f6": {
           "name": "f6",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": 0
-            }
-          ]
+          "result": 0
         },
         "f7": {
           "name": "f7",
@@ -66,11 +55,7 @@
               "type": "f32"
             }
           ],
-          "results": [
-            {
-              "type": 0
-            }
-          ]
+          "result": 0
         },
         "f8": {
           "name": "f8",
@@ -81,43 +66,7 @@
               "type": 1
             }
           ],
-          "results": [
-            {
-              "type": 2
-            }
-          ]
-        },
-        "f9": {
-          "name": "f9",
-          "kind": "freestanding",
-          "params": [],
-          "results": [
-            {
-              "name": "u",
-              "type": "u32"
-            },
-            {
-              "name": "f",
-              "type": "f32"
-            }
-          ]
-        },
-        "f10": {
-          "name": "f10",
-          "kind": "freestanding",
-          "params": [],
-          "results": [
-            {
-              "name": "u",
-              "type": "u32"
-            }
-          ]
-        },
-        "f11": {
-          "name": "f11",
-          "kind": "freestanding",
-          "params": [],
-          "results": []
+          "result": 2
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/import-export-overlap1.wit.json b/crates/wit-parser/tests/ui/import-export-overlap1.wit.json
index 0c88a177..40fa8998 100644
--- a/crates/wit-parser/tests/ui/import-export-overlap1.wit.json
+++ b/crates/wit-parser/tests/ui/import-export-overlap1.wit.json
@@ -7,8 +7,7 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
@@ -17,8 +16,7 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/import-export-overlap2.wit.json b/crates/wit-parser/tests/ui/import-export-overlap2.wit.json
index 0c991269..1c0e5974 100644
--- a/crates/wit-parser/tests/ui/import-export-overlap2.wit.json
+++ b/crates/wit-parser/tests/ui/import-export-overlap2.wit.json
@@ -7,8 +7,7 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/kebab-name-include-with.wit.json b/crates/wit-parser/tests/ui/kebab-name-include-with.wit.json
index 14c6d0d0..50fb7b5f 100644
--- a/crates/wit-parser/tests/ui/kebab-name-include-with.wit.json
+++ b/crates/wit-parser/tests/ui/kebab-name-include-with.wit.json
@@ -7,8 +7,7 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
@@ -22,8 +21,7 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
@@ -37,16 +35,14 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         },
         "a": {
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/multi-file.wit.json b/crates/wit-parser/tests/ui/multi-file.wit.json
index 45af0f5d..53bb14cb 100644
--- a/crates/wit-parser/tests/ui/multi-file.wit.json
+++ b/crates/wit-parser/tests/ui/multi-file.wit.json
@@ -34,11 +34,7 @@
             "name": "foo",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": 15
-              }
-            ]
+            "result": 15
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/packages-nested-internal-references.wit.json b/crates/wit-parser/tests/ui/packages-nested-internal-references.wit.json
index 0c26221a..d11a1215 100644
--- a/crates/wit-parser/tests/ui/packages-nested-internal-references.wit.json
+++ b/crates/wit-parser/tests/ui/packages-nested-internal-references.wit.json
@@ -41,8 +41,7 @@
               "name": "a",
               "type": 1
             }
-          ],
-          "results": []
+          ]
         }
       },
       "package": 1
diff --git a/crates/wit-parser/tests/ui/parse-fail/resources-multiple-returns-borrow.wit.result b/crates/wit-parser/tests/ui/parse-fail/resources-multiple-returns-borrow.wit.result
index ba5d4f7f..6831a3ac 100644
--- a/crates/wit-parser/tests/ui/parse-fail/resources-multiple-returns-borrow.wit.result
+++ b/crates/wit-parser/tests/ui/parse-fail/resources-multiple-returns-borrow.wit.result
@@ -1,5 +1,5 @@
-failed to update function `[method]r1.f1`: function returns a type which contains a `borrow<T>` which is not supported
-     --> tests/ui/parse-fail/resources-multiple-returns-borrow.wit:7:5
+expected a type, found '('
+     --> tests/ui/parse-fail/resources-multiple-returns-borrow.wit:4:30
       |
-    7 |     f1: func() -> (a: s32, handle: borrow<r1>);
-      |     ^-
\ No newline at end of file
+    4 |   t1: func(a: borrow<r1>) -> ();
+      |                              ^
\ No newline at end of file
diff --git a/crates/wit-parser/tests/ui/parse-fail/resources-return-borrow.wit.result b/crates/wit-parser/tests/ui/parse-fail/resources-return-borrow.wit.result
index b6a7361b..d91d1c0c 100644
--- a/crates/wit-parser/tests/ui/parse-fail/resources-return-borrow.wit.result
+++ b/crates/wit-parser/tests/ui/parse-fail/resources-return-borrow.wit.result
@@ -1,5 +1,5 @@
-failed to update function `[method]r1.f1`: function returns a type which contains a `borrow<T>` which is not supported
-     --> tests/ui/parse-fail/resources-return-borrow.wit:7:5
+expected a type, found '('
+     --> tests/ui/parse-fail/resources-return-borrow.wit:4:30
       |
-    7 |     f1: func() -> borrow<r1>;
-      |     ^-
\ No newline at end of file
+    4 |   t1: func(a: borrow<r1>) -> ();
+      |                              ^
\ No newline at end of file
diff --git a/crates/wit-parser/tests/ui/random.wit.json b/crates/wit-parser/tests/ui/random.wit.json
index 5d466646..dcf2178c 100644
--- a/crates/wit-parser/tests/ui/random.wit.json
+++ b/crates/wit-parser/tests/ui/random.wit.json
@@ -14,11 +14,7 @@
               "type": "u64"
             }
           ],
-          "results": [
-            {
-              "type": 0
-            }
-          ],
+          "result": 0,
           "docs": {
             "contents": "Return `len` cryptographically-secure random or pseudo-random bytes.\n\nThis function must produce data at least as cryptographically secure and\nfast as an adequately seeded cryptographically-secure pseudo-random\nnumber generator (CSPRNG). It must not block, from the perspective of\nthe calling program, under any circumstances, including on the first\nrequest and on requests for numbers of bytes. The returned data must\nalways be unpredictable.\n\nThis function must always return fresh data. Deterministic environments\nmust omit this function, rather than implementing it with deterministic\ndata."
           }
@@ -27,11 +23,7 @@
           "name": "get-random-u64",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": "u64"
-            }
-          ],
+          "result": "u64",
           "docs": {
             "contents": "Return a cryptographically-secure random or pseudo-random `u64` value.\n\nThis function returns the same type of data as `get-random-bytes`,\nrepresented as a `u64`."
           }
diff --git a/crates/wit-parser/tests/ui/resources-empty.wit b/crates/wit-parser/tests/ui/resources-empty.wit
index 62447351..876898eb 100644
--- a/crates/wit-parser/tests/ui/resources-empty.wit
+++ b/crates/wit-parser/tests/ui/resources-empty.wit
@@ -1,8 +1,8 @@
 package foo:resources-empty;
 
 interface resources-empty {
-  t1: func(a: own<r1>) -> ();
-  t2: func(a: borrow<r1>) -> ();
+  t1: func(a: own<r1>);
+  t2: func(a: borrow<r1>);
 
   resource r1 {
   }
diff --git a/crates/wit-parser/tests/ui/resources-empty.wit.json b/crates/wit-parser/tests/ui/resources-empty.wit.json
index 6c40c61d..4c16e496 100644
--- a/crates/wit-parser/tests/ui/resources-empty.wit.json
+++ b/crates/wit-parser/tests/ui/resources-empty.wit.json
@@ -15,8 +15,7 @@
               "name": "a",
               "type": 2
             }
-          ],
-          "results": []
+          ]
         },
         "t2": {
           "name": "t2",
@@ -26,8 +25,7 @@
               "name": "a",
               "type": 1
             }
-          ],
-          "results": []
+          ]
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit b/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit
index 13e87ffd..ca608da8 100644
--- a/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit
+++ b/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit
@@ -1,10 +1,10 @@
 package foo:resources1;
 
 interface resources1 {
-  t1: func(a: own<r1>) -> ();
+  t1: func(a: own<r1>);
 
   resource r1 {
-    f1: func() -> (a: s32, handle: own<r1>);
+    f1: func() -> tuple<s32, own<r1>>;
   }
 }
 
diff --git a/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit.json b/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit.json
index e7234f7e..f4d50ced 100644
--- a/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit.json
+++ b/crates/wit-parser/tests/ui/resources-multiple-returns-own.wit.json
@@ -15,8 +15,7 @@
               "name": "a",
               "type": 2
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f1": {
           "name": "[method]r1.f1",
@@ -29,16 +28,7 @@
               "type": 1
             }
           ],
-          "results": [
-            {
-              "name": "a",
-              "type": "s32"
-            },
-            {
-              "name": "handle",
-              "type": 2
-            }
-          ]
+          "result": 3
         }
       },
       "package": 0
@@ -69,6 +59,18 @@
         }
       },
       "owner": null
+    },
+    {
+      "name": null,
+      "kind": {
+        "tuple": {
+          "types": [
+            "s32",
+            2
+          ]
+        }
+      },
+      "owner": null
     }
   ],
   "packages": [
diff --git a/crates/wit-parser/tests/ui/resources-multiple.wit b/crates/wit-parser/tests/ui/resources-multiple.wit
index aee2d29a..221db5f6 100644
--- a/crates/wit-parser/tests/ui/resources-multiple.wit
+++ b/crates/wit-parser/tests/ui/resources-multiple.wit
@@ -1,8 +1,8 @@
 package foo:resources-multiple;
 
 interface resources-multiple {
-  t1: func(a: borrow<r1>) -> ();
-  t2: func(a: own<r1>) -> ();
+  t1: func(a: borrow<r1>);
+  t2: func(a: own<r1>);
 
   resource r1 {
     f1: func();
@@ -12,9 +12,6 @@ interface resources-multiple {
     f6: func() -> tuple<u32, u32>;
     f7: func(a: f32, b: f32) -> tuple<u32, u32>;
     f8: func(a: option<u32>) -> result<u32, f32>;
-    f9: func() -> (u: u32, f: f32);
-    f10: func() -> (u: u32);
-    f11: func() -> ();
   }
 }
 
diff --git a/crates/wit-parser/tests/ui/resources-multiple.wit.json b/crates/wit-parser/tests/ui/resources-multiple.wit.json
index 2914ab99..8b7969f2 100644
--- a/crates/wit-parser/tests/ui/resources-multiple.wit.json
+++ b/crates/wit-parser/tests/ui/resources-multiple.wit.json
@@ -15,8 +15,7 @@
               "name": "a",
               "type": 1
             }
-          ],
-          "results": []
+          ]
         },
         "t2": {
           "name": "t2",
@@ -26,8 +25,7 @@
               "name": "a",
               "type": 5
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f1": {
           "name": "[method]r1.f1",
@@ -39,8 +37,7 @@
               "name": "self",
               "type": 1
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f2": {
           "name": "[method]r1.f2",
@@ -56,8 +53,7 @@
               "name": "a",
               "type": "u32"
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f3": {
           "name": "[method]r1.f3",
@@ -73,8 +69,7 @@
               "name": "a",
               "type": "u32"
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f4": {
           "name": "[method]r1.f4",
@@ -87,11 +82,7 @@
               "type": 1
             }
           ],
-          "results": [
-            {
-              "type": "u32"
-            }
-          ]
+          "result": "u32"
         },
         "[method]r1.f6": {
           "name": "[method]r1.f6",
@@ -104,11 +95,7 @@
               "type": 1
             }
           ],
-          "results": [
-            {
-              "type": 2
-            }
-          ]
+          "result": 2
         },
         "[method]r1.f7": {
           "name": "[method]r1.f7",
@@ -129,11 +116,7 @@
               "type": "f32"
             }
           ],
-          "results": [
-            {
-              "type": 2
-            }
-          ]
+          "result": 2
         },
         "[method]r1.f8": {
           "name": "[method]r1.f8",
@@ -150,64 +133,7 @@
               "type": 3
             }
           ],
-          "results": [
-            {
-              "type": 4
-            }
-          ]
-        },
-        "[method]r1.f9": {
-          "name": "[method]r1.f9",
-          "kind": {
-            "method": 0
-          },
-          "params": [
-            {
-              "name": "self",
-              "type": 1
-            }
-          ],
-          "results": [
-            {
-              "name": "u",
-              "type": "u32"
-            },
-            {
-              "name": "f",
-              "type": "f32"
-            }
-          ]
-        },
-        "[method]r1.f10": {
-          "name": "[method]r1.f10",
-          "kind": {
-            "method": 0
-          },
-          "params": [
-            {
-              "name": "self",
-              "type": 1
-            }
-          ],
-          "results": [
-            {
-              "name": "u",
-              "type": "u32"
-            }
-          ]
-        },
-        "[method]r1.f11": {
-          "name": "[method]r1.f11",
-          "kind": {
-            "method": 0
-          },
-          "params": [
-            {
-              "name": "self",
-              "type": 1
-            }
-          ],
-          "results": []
+          "result": 4
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/resources-return-own.wit b/crates/wit-parser/tests/ui/resources-return-own.wit
index 0e36ac4b..4fa60639 100644
--- a/crates/wit-parser/tests/ui/resources-return-own.wit
+++ b/crates/wit-parser/tests/ui/resources-return-own.wit
@@ -1,7 +1,7 @@
 package foo:resources1;
 
 interface resources1 {
-  t1: func(a: own<r1>) -> ();
+  t1: func(a: own<r1>);
 
   resource r1 {
     f1: func() -> own<r1>;
diff --git a/crates/wit-parser/tests/ui/resources-return-own.wit.json b/crates/wit-parser/tests/ui/resources-return-own.wit.json
index 3e44fc10..290611e5 100644
--- a/crates/wit-parser/tests/ui/resources-return-own.wit.json
+++ b/crates/wit-parser/tests/ui/resources-return-own.wit.json
@@ -15,8 +15,7 @@
               "name": "a",
               "type": 2
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f1": {
           "name": "[method]r1.f1",
@@ -29,11 +28,7 @@
               "type": 1
             }
           ],
-          "results": [
-            {
-              "type": 2
-            }
-          ]
+          "result": 2
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/resources.wit.json b/crates/wit-parser/tests/ui/resources.wit.json
index 169fb021..accbf318 100644
--- a/crates/wit-parser/tests/ui/resources.wit.json
+++ b/crates/wit-parser/tests/ui/resources.wit.json
@@ -19,11 +19,7 @@
               "constructor": 13
             },
             "params": [],
-            "results": [
-              {
-                "type": 18
-              }
-            ]
+            "result": 18
           }
         }
       },
@@ -48,11 +44,7 @@
             "constructor": 1
           },
           "params": [],
-          "results": [
-            {
-              "type": 14
-            }
-          ]
+          "result": 14
         },
         "[constructor]c": {
           "name": "[constructor]c",
@@ -65,11 +57,7 @@
               "type": "u32"
             }
           ],
-          "results": [
-            {
-              "type": 15
-            }
-          ]
+          "result": 15
         },
         "[constructor]d": {
           "name": "[constructor]d",
@@ -82,11 +70,7 @@
               "type": "u32"
             }
           ],
-          "results": [
-            {
-              "type": 16
-            }
-          ]
+          "result": 16
         },
         "[method]d.a": {
           "name": "[method]d.a",
@@ -98,16 +82,14 @@
               "name": "self",
               "type": 5
             }
-          ],
-          "results": []
+          ]
         },
         "[static]d.b": {
           "name": "[static]d.b",
           "kind": {
             "static": 3
           },
-          "params": [],
-          "results": []
+          "params": []
         },
         "[constructor]e": {
           "name": "[constructor]e",
@@ -124,11 +106,7 @@
               "type": 6
             }
           ],
-          "results": [
-            {
-              "type": 17
-            }
-          ]
+          "result": 17
         },
         "[method]e.method": {
           "name": "[method]e.method",
@@ -148,8 +126,7 @@
               "name": "thing2",
               "type": 6
             }
-          ],
-          "results": []
+          ]
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/resources1.wit b/crates/wit-parser/tests/ui/resources1.wit
index 77baeffe..901f07da 100644
--- a/crates/wit-parser/tests/ui/resources1.wit
+++ b/crates/wit-parser/tests/ui/resources1.wit
@@ -1,9 +1,9 @@
 package foo:resources1;
 
 interface resources1 {
-  t1: func(a: borrow<r1>) -> ();
-  t2: func(a: own<r1>) -> ();
-  t3: func(a: r1) -> ();
+  t1: func(a: borrow<r1>);
+  t2: func(a: own<r1>);
+  t3: func(a: r1);
 
   resource r1 {
     f1: func();
diff --git a/crates/wit-parser/tests/ui/resources1.wit.json b/crates/wit-parser/tests/ui/resources1.wit.json
index 447e5ec2..3bb1da4b 100644
--- a/crates/wit-parser/tests/ui/resources1.wit.json
+++ b/crates/wit-parser/tests/ui/resources1.wit.json
@@ -15,8 +15,7 @@
               "name": "a",
               "type": 1
             }
-          ],
-          "results": []
+          ]
         },
         "t2": {
           "name": "t2",
@@ -26,8 +25,7 @@
               "name": "a",
               "type": 2
             }
-          ],
-          "results": []
+          ]
         },
         "t3": {
           "name": "t3",
@@ -37,8 +35,7 @@
               "name": "a",
               "type": 2
             }
-          ],
-          "results": []
+          ]
         },
         "[method]r1.f1": {
           "name": "[method]r1.f1",
@@ -50,8 +47,7 @@
               "name": "self",
               "type": 1
             }
-          ],
-          "results": []
+          ]
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/same-name-import-export.wit.json b/crates/wit-parser/tests/ui/same-name-import-export.wit.json
index 3cf1798d..ac0647ee 100644
--- a/crates/wit-parser/tests/ui/same-name-import-export.wit.json
+++ b/crates/wit-parser/tests/ui/same-name-import-export.wit.json
@@ -8,11 +8,7 @@
             "name": "greet",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": "string"
-              }
-            ]
+            "result": "string"
           }
         }
       },
@@ -22,11 +18,7 @@
             "name": "greet",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": "string"
-              }
-            ]
+            "result": "string"
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/shared-types.wit.json b/crates/wit-parser/tests/ui/shared-types.wit.json
index 569f6d38..8f53710b 100644
--- a/crates/wit-parser/tests/ui/shared-types.wit.json
+++ b/crates/wit-parser/tests/ui/shared-types.wit.json
@@ -28,11 +28,7 @@
           "name": "a",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": 0
-            }
-          ]
+          "result": 0
         }
       },
       "package": 0
@@ -45,11 +41,7 @@
           "name": "a",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": 1
-            }
-          ]
+          "result": 1
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/since-and-unstable.wit.json b/crates/wit-parser/tests/ui/since-and-unstable.wit.json
index a4b75947..ad483746 100644
--- a/crates/wit-parser/tests/ui/since-and-unstable.wit.json
+++ b/crates/wit-parser/tests/ui/since-and-unstable.wit.json
@@ -51,7 +51,6 @@
             "name": "x",
             "kind": "freestanding",
             "params": [],
-            "results": [],
             "stability": {
               "stable": {
                 "since": "1.0.0"
@@ -86,11 +85,7 @@
               "constructor": 17
             },
             "params": [],
-            "results": [
-              {
-                "type": 19
-              }
-            ],
+            "result": 19,
             "stability": {
               "stable": {
                 "since": "1.0.0"
@@ -105,7 +100,6 @@
             "name": "x",
             "kind": "freestanding",
             "params": [],
-            "results": [],
             "stability": {
               "stable": {
                 "since": "1.0.0"
@@ -188,7 +182,6 @@
           "name": "foo",
           "kind": "freestanding",
           "params": [],
-          "results": [],
           "stability": {
             "stable": {
               "since": "1.0.0"
@@ -201,11 +194,7 @@
             "constructor": 7
           },
           "params": [],
-          "results": [
-            {
-              "type": 18
-            }
-          ],
+          "result": 18,
           "stability": {
             "stable": {
               "since": "1.0.0"
@@ -218,7 +207,6 @@
             "static": 7
           },
           "params": [],
-          "results": [],
           "stability": {
             "stable": {
               "since": "1.0.0"
@@ -236,7 +224,6 @@
               "type": 8
             }
           ],
-          "results": [],
           "stability": {
             "stable": {
               "since": "1.0.0"
diff --git a/crates/wit-parser/tests/ui/streams-and-futures.wit.json b/crates/wit-parser/tests/ui/streams-and-futures.wit.json
index 79866b1e..8a0b2953 100644
--- a/crates/wit-parser/tests/ui/streams-and-futures.wit.json
+++ b/crates/wit-parser/tests/ui/streams-and-futures.wit.json
@@ -28,11 +28,7 @@
               "type": 11
             }
           ],
-          "results": [
-            {
-              "type": 18
-            }
-          ]
+          "result": 18
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/type-then-eof.wit.json b/crates/wit-parser/tests/ui/type-then-eof.wit.json
index beb0a7ad..54ecd5ed 100644
--- a/crates/wit-parser/tests/ui/type-then-eof.wit.json
+++ b/crates/wit-parser/tests/ui/type-then-eof.wit.json
@@ -9,11 +9,7 @@
           "name": "foo",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": "string"
-            }
-          ]
+          "result": "string"
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/union-fuzz-2.wit b/crates/wit-parser/tests/ui/union-fuzz-2.wit
index 771dc320..ec733e96 100644
--- a/crates/wit-parser/tests/ui/union-fuzz-2.wit
+++ b/crates/wit-parser/tests/ui/union-fuzz-2.wit
@@ -1,7 +1,7 @@
 package foo:bar;
 
 world foo {
-    export foo: func() -> (%name2: f32);
+    export foo: func() -> f32;
 }
 
 
diff --git a/crates/wit-parser/tests/ui/union-fuzz-2.wit.json b/crates/wit-parser/tests/ui/union-fuzz-2.wit.json
index 6d1bc4ff..36de6b23 100644
--- a/crates/wit-parser/tests/ui/union-fuzz-2.wit.json
+++ b/crates/wit-parser/tests/ui/union-fuzz-2.wit.json
@@ -9,12 +9,7 @@
             "name": "foo",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "name": "name2",
-                "type": "f32"
-              }
-            ]
+            "result": "f32"
           }
         }
       },
@@ -33,12 +28,7 @@
             "name": "foo",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "name": "name2",
-                "type": "f32"
-              }
-            ]
+            "result": "f32"
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/use.wit.json b/crates/wit-parser/tests/ui/use.wit.json
index 43cc16b4..704bcdaa 100644
--- a/crates/wit-parser/tests/ui/use.wit.json
+++ b/crates/wit-parser/tests/ui/use.wit.json
@@ -54,11 +54,7 @@
               "type": 4
             }
           ],
-          "results": [
-            {
-              "type": 5
-            }
-          ]
+          "result": 5
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/world-diamond.wit.json b/crates/wit-parser/tests/ui/world-diamond.wit.json
index 6dba45ed..657c5b9c 100644
--- a/crates/wit-parser/tests/ui/world-diamond.wit.json
+++ b/crates/wit-parser/tests/ui/world-diamond.wit.json
@@ -22,8 +22,7 @@
           "function": {
             "name": "a",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
@@ -50,11 +49,7 @@
           "name": "a",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": 1
-            }
-          ]
+          "result": 1
         }
       },
       "package": 0
@@ -69,11 +64,7 @@
           "name": "a",
           "kind": "freestanding",
           "params": [],
-          "results": [
-            {
-              "type": 2
-            }
-          ]
+          "result": 2
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/world-iface-no-collide.wit.json b/crates/wit-parser/tests/ui/world-iface-no-collide.wit.json
index fffc1155..4e86a4da 100644
--- a/crates/wit-parser/tests/ui/world-iface-no-collide.wit.json
+++ b/crates/wit-parser/tests/ui/world-iface-no-collide.wit.json
@@ -15,8 +15,7 @@
           "function": {
             "name": "foo",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/world-implicit-import2.wit.json b/crates/wit-parser/tests/ui/world-implicit-import2.wit.json
index 97049842..25ab96a5 100644
--- a/crates/wit-parser/tests/ui/world-implicit-import2.wit.json
+++ b/crates/wit-parser/tests/ui/world-implicit-import2.wit.json
@@ -16,11 +16,7 @@
             "name": "foo",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": 1
-              }
-            ]
+            "result": 1
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/world-implicit-import3.wit.json b/crates/wit-parser/tests/ui/world-implicit-import3.wit.json
index 159bee77..3036f69c 100644
--- a/crates/wit-parser/tests/ui/world-implicit-import3.wit.json
+++ b/crates/wit-parser/tests/ui/world-implicit-import3.wit.json
@@ -18,11 +18,7 @@
             "name": "foo",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": 1
-              }
-            ]
+            "result": 1
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/world-top-level-funcs.wit.json b/crates/wit-parser/tests/ui/world-top-level-funcs.wit.json
index b7866aa1..df491f23 100644
--- a/crates/wit-parser/tests/ui/world-top-level-funcs.wit.json
+++ b/crates/wit-parser/tests/ui/world-top-level-funcs.wit.json
@@ -7,8 +7,7 @@
           "function": {
             "name": "foo",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         },
         "bar": {
@@ -20,8 +19,7 @@
                 "name": "arg",
                 "type": 0
               }
-            ],
-            "results": []
+            ]
           }
         }
       },
@@ -30,8 +28,7 @@
           "function": {
             "name": "foo2",
             "kind": "freestanding",
-            "params": [],
-            "results": []
+            "params": []
           }
         },
         "some-name": {
@@ -39,11 +36,7 @@
             "name": "some-name",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": 2
-              }
-            ]
+            "result": 2
           }
         }
       },
diff --git a/crates/wit-parser/tests/ui/world-top-level-resources.wit.json b/crates/wit-parser/tests/ui/world-top-level-resources.wit.json
index 794e699f..0babd96f 100644
--- a/crates/wit-parser/tests/ui/world-top-level-resources.wit.json
+++ b/crates/wit-parser/tests/ui/world-top-level-resources.wit.json
@@ -42,8 +42,7 @@
               "name": "self",
               "type": 2
             }
-          ],
-          "results": []
+          ]
         },
         "[method]request.bar": {
           "name": "[method]request.bar",
@@ -59,8 +58,7 @@
               "name": "arg",
               "type": 3
             }
-          ],
-          "results": []
+          ]
         },
         "[method]response.foo": {
           "name": "[method]response.foo",
@@ -72,8 +70,7 @@
               "name": "self",
               "type": 4
             }
-          ],
-          "results": []
+          ]
         },
         "[method]response.bar": {
           "name": "[method]response.bar",
@@ -89,8 +86,7 @@
               "name": "arg",
               "type": 3
             }
-          ],
-          "results": []
+          ]
         }
       },
       "package": 0
@@ -111,11 +107,7 @@
               "type": 7
             }
           ],
-          "results": [
-            {
-              "type": 8
-            }
-          ]
+          "result": 8
         },
         "handle-owned": {
           "name": "handle-owned",
@@ -126,11 +118,7 @@
               "type": 9
             }
           ],
-          "results": [
-            {
-              "type": 8
-            }
-          ]
+          "result": 8
         }
       },
       "package": 0
diff --git a/crates/wit-parser/tests/ui/worlds-with-types.wit.json b/crates/wit-parser/tests/ui/worlds-with-types.wit.json
index 70e857d6..19ccefac 100644
--- a/crates/wit-parser/tests/ui/worlds-with-types.wit.json
+++ b/crates/wit-parser/tests/ui/worlds-with-types.wit.json
@@ -21,11 +21,7 @@
                 "type": 1
               }
             ],
-            "results": [
-              {
-                "type": 2
-              }
-            ]
+            "result": 2
           }
         }
       },
@@ -49,11 +45,7 @@
             "name": "foo",
             "kind": "freestanding",
             "params": [],
-            "results": [
-              {
-                "type": 3
-              }
-            ]
+            "result": 3
           }
         }
       },
@@ -78,11 +70,7 @@
                 "type": 4
               }
             ],
-            "results": [
-              {
-                "type": 5
-              }
-            ]
+            "result": 5
           }
         }
       },
@@ -97,11 +85,7 @@
                 "type": 4
               }
             ],
-            "results": [
-              {
-                "type": 5
-              }
-            ]
+            "result": 5
           }
         }
       },
diff --git a/tests/cli/dump/alias.wat.stdout b/tests/cli/dump/alias.wat.stdout
index aa444eaf..71000130 100644
--- a/tests/cli/dump/alias.wat.stdout
+++ b/tests/cli/dump/alias.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 1f       | component type section
   0xa | 01          | 1 count
-  0xb | 42 04 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("f1"), ty: Func(0) }, Type(Func(ComponentFuncType { params: [("p1", Primitive(String))], results: Named([]) })), Export { name: ComponentExportName("f2"), ty: Func(1) }])
+  0xb | 42 04 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], result: None })), Export { name: ComponentExportName("f1"), ty: Func(0) }, Type(Func(ComponentFuncType { params: [("p1", Primitive(String))], result: None })), Export { name: ComponentExportName("f2"), ty: Func(1) }])
       | 00 01 00 04
       | 00 02 66 31
       | 01 00 01 40
diff --git a/tests/cli/dump/alias2.wat.stdout b/tests/cli/dump/alias2.wat.stdout
index c88baade..47695fca 100644
--- a/tests/cli/dump/alias2.wat.stdout
+++ b/tests/cli/dump/alias2.wat.stdout
@@ -2,7 +2,7 @@
        | 0d 00 01 00
    0x8 | 07 30       | component type section
    0xa | 01          | 1 count
-   0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: ComponentExportName("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("b"), ty: Func(0) }, Export { name: ComponentExportName("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: ComponentExportName("d"), ty: Instance(1) }, Type(Component([])), Export { name: ComponentExportName("e"), ty: Component(2) }])
+   0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: ComponentExportName("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], result: None })), Export { name: ComponentExportName("b"), ty: Func(0) }, Export { name: ComponentExportName("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: ComponentExportName("d"), ty: Instance(1) }, Type(Component([])), Export { name: ComponentExportName("e"), ty: Component(2) }])
        | 00 04 00 01
        | 61 00 11 00
        | 01 40 00 01
@@ -30,7 +30,7 @@
          | 11 00      
     0x5a | 07 05       | component type section
     0x5c | 01          | 1 count
-    0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], results: Named([]) })
+    0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], result: None })
     0x61 | 0a 0b       | component import section
     0x63 | 02          | 2 count
     0x64 | 00 01 62 01 | [func 0] ComponentImport { name: ComponentImportName("b"), ty: Func(0) }
diff --git a/tests/cli/dump/bundled.wat.stdout b/tests/cli/dump/bundled.wat.stdout
index a2d5d6ea..ff40ee87 100644
--- a/tests/cli/dump/bundled.wat.stdout
+++ b/tests/cli/dump/bundled.wat.stdout
@@ -2,7 +2,7 @@
        | 0d 00 01 00
    0x8 | 07 30       | component type section
    0xa | 01          | 1 count
-   0xb | 42 06 01 70 | [type 0] Instance([Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("len", Primitive(U32))], results: Unnamed(Type(0)) })), Export { name: ComponentExportName("read"), ty: Func(1) }, Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("buf", Type(2))], results: Unnamed(Primitive(U32)) })), Export { name: ComponentExportName("write"), ty: Func(3) }])
+   0xb | 42 06 01 70 | [type 0] Instance([Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("len", Primitive(U32))], result: Some(Type(0)) })), Export { name: ComponentExportName("read"), ty: Func(1) }, Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("buf", Type(2))], result: Some(Primitive(U32)) })), Export { name: ComponentExportName("write"), ty: Func(3) }])
        | 7d 01 40 01
        | 03 6c 65 6e
        | 79 00 00 04
@@ -176,7 +176,7 @@
        | 65 12 02   
  0x1ad | 07 05       | component type section
  0x1af | 01          | 1 count
- 0x1b0 | 40 00 01 00 | [type 1] Func(ComponentFuncType { params: [], results: Named([]) })
+ 0x1b0 | 40 00 01 00 | [type 1] Func(ComponentFuncType { params: [], result: None })
  0x1b4 | 06 1e       | component alias section
  0x1b6 | 03          | 3 count
  0x1b7 | 00 00 01 03 | alias [core func 2] CoreInstanceExport { kind: Func, instance_index: 3, name: "play" }
diff --git a/tests/cli/dump/component-inline-type.wat.stdout b/tests/cli/dump/component-inline-type.wat.stdout
index 638b08b0..8023a9b0 100644
--- a/tests/cli/dump/component-inline-type.wat.stdout
+++ b/tests/cli/dump/component-inline-type.wat.stdout
@@ -23,7 +23,7 @@
       | 01         
  0x30 | 07 05       | component type section
  0x32 | 01          | 1 count
- 0x33 | 40 00 01 00 | [type 2] Func(ComponentFuncType { params: [], results: Named([]) })
+ 0x33 | 40 00 01 00 | [type 2] Func(ComponentFuncType { params: [], result: None })
  0x37 | 0a 06       | component import section
  0x39 | 01          | 1 count
  0x3a | 00 01 64 01 | [func 0] ComponentImport { name: ComponentImportName("d"), ty: Func(2) }
diff --git a/tests/cli/dump/component-instance-type.wat.stdout b/tests/cli/dump/component-instance-type.wat.stdout
index 7e5301b4..52b5bdc4 100644
--- a/tests/cli/dump/component-instance-type.wat.stdout
+++ b/tests/cli/dump/component-instance-type.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 28       | component type section
   0xa | 01          | 1 count
-  0xb | 42 03 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Type(Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Alias(Outer { kind: Type, count: 1, index: 0 }), Import(ComponentImport { name: ComponentImportName("1"), ty: Func(0) }), Export { name: ComponentExportName("1"), ty: Func(1) }])), Export { name: ComponentExportName("c5"), ty: Component(1) }])
+  0xb | 42 03 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], result: None })), Type(Component([Type(Func(ComponentFuncType { params: [], result: None })), Alias(Outer { kind: Type, count: 1, index: 0 }), Import(ComponentImport { name: ComponentImportName("1"), ty: Func(0) }), Export { name: ComponentExportName("1"), ty: Func(1) }])), Export { name: ComponentExportName("c5"), ty: Component(1) }])
       | 00 01 00 01
       | 41 04 01 40
       | 00 01 00 02
diff --git a/tests/cli/dump/component-linking.wat.stdout b/tests/cli/dump/component-linking.wat.stdout
index 4dd685fa..c69dec64 100644
--- a/tests/cli/dump/component-linking.wat.stdout
+++ b/tests/cli/dump/component-linking.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 30       | component type section
   0xa | 01          | 1 count
-  0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: ComponentExportName("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("b"), ty: Func(0) }, Export { name: ComponentExportName("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: ComponentExportName("d"), ty: Instance(1) }, Type(Component([])), Export { name: ComponentExportName("e"), ty: Component(2) }])
+  0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: ComponentExportName("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], result: None })), Export { name: ComponentExportName("b"), ty: Func(0) }, Export { name: ComponentExportName("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: ComponentExportName("d"), ty: Instance(1) }, Type(Component([])), Export { name: ComponentExportName("e"), ty: Component(2) }])
       | 00 04 00 01
       | 61 00 11 00
       | 01 40 00 01
@@ -30,7 +30,7 @@
         | 11 00      
    0x5a | 07 05       | component type section
    0x5c | 01          | 1 count
-   0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], results: Named([]) })
+   0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], result: None })
    0x61 | 0a 0b       | component import section
    0x63 | 02          | 2 count
    0x64 | 00 01 62 01 | [func 0] ComponentImport { name: ComponentImportName("b"), ty: Func(0) }
diff --git a/tests/cli/dump/component-outer-alias.wat.stdout b/tests/cli/dump/component-outer-alias.wat.stdout
index d78a1e98..7ce95d09 100644
--- a/tests/cli/dump/component-outer-alias.wat.stdout
+++ b/tests/cli/dump/component-outer-alias.wat.stdout
@@ -3,7 +3,7 @@
   0x8 | 07 0e       | component type section
   0xa | 02          | 2 count
   0xb | 73          | [type 0] Defined(Primitive(String))
-  0xc | 41 02 02 03 | [type 1] Component([Alias(Outer { kind: Type, count: 1, index: 0 }), Type(Func(ComponentFuncType { params: [], results: Unnamed(Type(0)) }))])
+  0xc | 41 02 02 03 | [type 1] Component([Alias(Outer { kind: Type, count: 1, index: 0 }), Type(Func(ComponentFuncType { params: [], result: Some(Type(0)) }))])
       | 02 01 00 01
       | 40 00 00 00
  0x18 | 04 2e       | [component 0] inline size
@@ -14,7 +14,7 @@
    0x25 | 03 02 01 00 | alias [type 0] Outer { kind: Type, count: 1, index: 0 }
    0x29 | 07 05       | component type section
    0x2b | 01          | 1 count
-   0x2c | 40 00 00 00 | [type 1] Func(ComponentFuncType { params: [], results: Unnamed(Type(0)) })
+   0x2c | 40 00 00 00 | [type 1] Func(ComponentFuncType { params: [], result: Some(Type(0)) })
    0x30 | 00 16       | custom section
    0x32 | 0e 63 6f 6d | name: "component-name"
         | 70 6f 6e 65
@@ -31,8 +31,8 @@
    0x55 | 03 02 01 00 | alias [type 0] Outer { kind: Type, count: 1, index: 0 }
    0x59 | 07 09       | component type section
    0x5b | 02          | 2 count
-   0x5c | 40 00 00 00 | [type 1] Func(ComponentFuncType { params: [], results: Unnamed(Type(0)) })
-   0x60 | 40 00 00 00 | [type 2] Func(ComponentFuncType { params: [], results: Unnamed(Type(0)) })
+   0x5c | 40 00 00 00 | [type 1] Func(ComponentFuncType { params: [], result: Some(Type(0)) })
+   0x60 | 40 00 00 00 | [type 2] Func(ComponentFuncType { params: [], result: Some(Type(0)) })
    0x64 | 00 16       | custom section
    0x66 | 0e 63 6f 6d | name: "component-name"
         | 70 6f 6e 65
@@ -52,8 +52,8 @@
    0x8d | 03 02 01 02 | alias [type 0] Outer { kind: Type, count: 1, index: 2 }
    0x91 | 07 09       | component type section
    0x93 | 02          | 2 count
-   0x94 | 40 00 00 00 | [type 1] Func(ComponentFuncType { params: [], results: Unnamed(Type(0)) })
-   0x98 | 40 00 00 00 | [type 2] Func(ComponentFuncType { params: [], results: Unnamed(Type(0)) })
+   0x94 | 40 00 00 00 | [type 1] Func(ComponentFuncType { params: [], result: Some(Type(0)) })
+   0x98 | 40 00 00 00 | [type 2] Func(ComponentFuncType { params: [], result: Some(Type(0)) })
    0x9c | 00 17       | custom section
    0x9e | 0e 63 6f 6d | name: "component-name"
         | 70 6f 6e 65
diff --git a/tests/cli/dump/instance-expand.wat.stdout b/tests/cli/dump/instance-expand.wat.stdout
index c61e1f9a..d90ee35d 100644
--- a/tests/cli/dump/instance-expand.wat.stdout
+++ b/tests/cli/dump/instance-expand.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 0d       | component type section
   0xa | 01          | 1 count
-  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName(""), ty: Func(0) }])
+  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], result: None })), Export { name: ComponentExportName(""), ty: Func(0) }])
       | 00 01 00 04
       | 00 00 01 00
  0x17 | 0a 06       | component import section
diff --git a/tests/cli/dump/instance-type.wat.stdout b/tests/cli/dump/instance-type.wat.stdout
index 1dc2a523..0fecf8a8 100644
--- a/tests/cli/dump/instance-type.wat.stdout
+++ b/tests/cli/dump/instance-type.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 17       | component type section
   0xa | 02          | 2 count
-  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName(""), ty: Func(0) }])
+  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], result: None })), Export { name: ComponentExportName(""), ty: Func(0) }])
       | 00 01 00 04
       | 00 00 01 00
  0x17 | 42 02 01 42 | [type 1] Instance([Type(Instance([])), Export { name: ComponentExportName(""), ty: Instance(0) }])
diff --git a/tests/cli/dump/instantiate.wat.stdout b/tests/cli/dump/instantiate.wat.stdout
index eb3537a3..edd401fb 100644
--- a/tests/cli/dump/instantiate.wat.stdout
+++ b/tests/cli/dump/instantiate.wat.stdout
@@ -9,7 +9,7 @@
       | 00         
  0x15 | 07 05       | component type section
  0x17 | 01          | 1 count
- 0x18 | 40 00 01 00 | [type 1] Func(ComponentFuncType { params: [], results: Named([]) })
+ 0x18 | 40 00 01 00 | [type 1] Func(ComponentFuncType { params: [], result: None })
  0x1c | 0a 06       | component import section
  0x1e | 01          | 1 count
  0x1f | 00 01 66 01 | [func 0] ComponentImport { name: ComponentImportName("f"), ty: Func(1) }
diff --git a/tests/cli/dump/instantiate2.wat.stdout b/tests/cli/dump/instantiate2.wat.stdout
index 19ccd6ea..bf505f38 100644
--- a/tests/cli/dump/instantiate2.wat.stdout
+++ b/tests/cli/dump/instantiate2.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 0e       | component type section
   0xa | 01          | 1 count
-  0xb | 41 02 01 40 | [type 0] Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Import(ComponentImport { name: ComponentImportName("a"), ty: Func(0) })])
+  0xb | 41 02 01 40 | [type 0] Component([Type(Func(ComponentFuncType { params: [], result: None })), Import(ComponentImport { name: ComponentImportName("a"), ty: Func(0) })])
       | 00 01 00 03
       | 00 01 61 01
       | 00         
diff --git a/tests/cli/dump/nested-component.wat.stdout b/tests/cli/dump/nested-component.wat.stdout
index ec185c19..3a412280 100644
--- a/tests/cli/dump/nested-component.wat.stdout
+++ b/tests/cli/dump/nested-component.wat.stdout
@@ -35,7 +35,7 @@
      0x64 | 01 6d       | "m"
    0x66 | 07 08       | component type section
    0x68 | 01          | 1 count
-   0x69 | 40 01 01 70 | [type 0] Func(ComponentFuncType { params: [("p", Primitive(String))], results: Named([]) })
+   0x69 | 40 01 01 70 | [type 0] Func(ComponentFuncType { params: [("p", Primitive(String))], result: None })
         | 73 01 00   
    0x70 | 0a 06       | component import section
    0x72 | 01          | 1 count
@@ -47,7 +47,7 @@
         | 11 00 00   
    0x82 | 07 0e       | component type section
    0x84 | 01          | 1 count
-   0x85 | 42 02 01 40 | [type 1] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("a"), ty: Func(0) }])
+   0x85 | 42 02 01 40 | [type 1] Instance([Type(Func(ComponentFuncType { params: [], result: None })), Export { name: ComponentExportName("a"), ty: Func(0) }])
         | 00 01 00 04
         | 00 01 61 01
         | 00         
diff --git a/tests/cli/validate-unknown-features.wat.stderr b/tests/cli/validate-unknown-features.wat.stderr
index c337c23b..c7799ed9 100644
--- a/tests/cli/validate-unknown-features.wat.stderr
+++ b/tests/cli/validate-unknown-features.wat.stderr
@@ -1,4 +1,4 @@
 error: invalid value 'unknown' for '--features <FEATURES>': unknown feature `unknown`
-Valid features: mutable-global, saturating-float-to-int, sign-extension, reference-types, multi-value, bulk-memory, simd, relaxed-simd, threads, shared-everything-threads, tail-call, floats, multi-memory, exceptions, memory64, extended-const, component-model, function-references, memory-control, gc, custom-page-sizes, component-model-values, component-model-nested-names, component-model-more-flags, component-model-multiple-returns, legacy-exceptions, gc-types, stack-switching, wide-arithmetic, component-model-async, mvp, wasm1, wasm2, wasm3, all
+Valid features: mutable-global, saturating-float-to-int, sign-extension, reference-types, multi-value, bulk-memory, simd, relaxed-simd, threads, shared-everything-threads, tail-call, floats, multi-memory, exceptions, memory64, extended-const, component-model, function-references, memory-control, gc, custom-page-sizes, component-model-values, component-model-nested-names, legacy-exceptions, gc-types, stack-switching, wide-arithmetic, component-model-async, mvp, wasm1, wasm2, wasm3, all
 
 For more information, try '--help'.
diff --git a/tests/local/component-model/func.wast b/tests/local/component-model/func.wast
index f5ec7113..d9446f02 100644
--- a/tests/local/component-model/func.wast
+++ b/tests/local/component-model/func.wast
@@ -1,15 +1,9 @@
 (component
   (import "a" (func (param "foo" string)))
   (import "b" (func (param "foo" string) (param "bar" s32) (param "baz" u32)))
-  (import "c" (func (result "foo" (tuple u8))))
+  (import "c" (func (result (tuple u8))))
 )
 
-(assert_invalid
-  (component
-    (import "a" (func (result "foo" string) (result "bar" s32) (result "baz" u32)))
-  )
-  "multiple returns on a function is now a gated feature")
-
 (component
   (import "a" (func))
   (import "b" (func (param "p1" string)))
@@ -25,7 +19,6 @@
   "function parameter name `FOO` conflicts with previous parameter name `foo`"
 )
 
-
 (assert_invalid
   (component
       (core module $m
@@ -127,3 +120,25 @@
   )
   "canonical option `realloc` is required"
 )
+
+(assert_invalid
+  (component binary
+    "\00asm" "\0d\00\01\00"   ;; component header
+    "\07\05"          ;; component type section, 5 bytes
+    "\01"             ;; 1 count
+    "\40"             ;; component function type
+    "\00"             ;; 0 parameters
+    "\01\01"          ;; invalid result encoding
+  )
+  "invalid leading byte (0x1) for number of results")
+
+(assert_invalid
+  (component binary
+    "\00asm" "\0d\00\01\00"   ;; component header
+    "\07\05"          ;; component type section, 5 bytes
+    "\01"             ;; 1 count
+    "\40"             ;; component function type
+    "\00"             ;; 0 parameters
+    "\02\00"          ;; invalid result encoding
+  )
+  "invalid leading byte (0x2) for component function results")
diff --git a/tests/local/component-model/instantiate.wast b/tests/local/component-model/instantiate.wast
index 9583d697..f8133421 100644
--- a/tests/local/component-model/instantiate.wast
+++ b/tests/local/component-model/instantiate.wast
@@ -185,7 +185,7 @@
     (import "b" (func $f (result string)))
     (instance $i (instantiate $m (with "a" (func $f))))
   )
-  "expected 0 results, found 1")
+  "expected a result, found none")
 
 (assert_invalid
   (component
@@ -708,19 +708,9 @@
   "type mismatch in function parameter `x`")
 (assert_invalid
   (component
-    (import "x" (func $x (result "x" u32)))
+    (import "x" (func $x (result u32)))
     (import "y" (component $c
-      (import "x" (func (result "y" u32)))
-    ))
-
-    (instance (instantiate $c (with "x" (func $x))))
-  )
-  "mismatched result names")
-(assert_invalid
-  (component
-    (import "x" (func $x (result "x" u32)))
-    (import "y" (component $c
-      (import "x" (func (result "x" s32)))
+      (import "x" (func (result s32)))
     ))
 
     (instance (instantiate $c (with "x" (func $x))))
diff --git a/tests/local/component-model/more-flags.wast b/tests/local/component-model/more-flags.wast
index 6d17e450..64063153 100644
--- a/tests/local/component-model/more-flags.wast
+++ b/tests/local/component-model/more-flags.wast
@@ -1,37 +1,39 @@
-(component
-  (type (flags
-    "f1"
-    "f2"
-    "f3"
-    "f4"
-    "f5"
-    "f6"
-    "f7"
-    "f8"
-    "f9"
-    "f10"
-    "f11"
-    "f12"
-    "f13"
-    "f14"
-    "f15"
-    "f16"
-    "f17"
-    "f18"
-    "f19"
-    "f20"
-    "f21"
-    "f22"
-    "f23"
-    "f24"
-    "f25"
-    "f26"
-    "f27"
-    "f28"
-    "f29"
-    "f30"
-    "f31"
-    "f32"
-    "f33"
-  ))
-)
+(assert_invalid
+  (component
+    (type (flags
+      "f1"
+      "f2"
+      "f3"
+      "f4"
+      "f5"
+      "f6"
+      "f7"
+      "f8"
+      "f9"
+      "f10"
+      "f11"
+      "f12"
+      "f13"
+      "f14"
+      "f15"
+      "f16"
+      "f17"
+      "f18"
+      "f19"
+      "f20"
+      "f21"
+      "f22"
+      "f23"
+      "f24"
+      "f25"
+      "f26"
+      "f27"
+      "f28"
+      "f29"
+      "f30"
+      "f31"
+      "f32"
+      "f33"
+    ))
+  )
+  "cannot have more than 32 flags")
diff --git a/tests/local/component-model/multiple-returns.wast b/tests/local/component-model/multiple-returns.wast
deleted file mode 100644
index d8173fa4..00000000
--- a/tests/local/component-model/multiple-returns.wast
+++ /dev/null
@@ -1,37 +0,0 @@
-(component
-  (import "a" (func (result "foo" string) (result "bar" s32) (result "baz" u32)))
-)
-
-(component
-  (import "a" (func $f (param "a" string) (param "b" string) (result "c" s32) (result "d" s32)))
-  (import "b" (value $v string))
-  (import "c" (value $v2 string))
-  (start $f (value $v) (value $v2) (result (value $c)) (result (value $d)))
-  (export "d" (value $c))
-  (export "e" (value $d))
-)
-
-(assert_invalid
-  (component
-    (import "a" (func $f (param "a" string) (param "b" string) (result "c" s32) (result "d" s32)))
-    (import "b" (value $v string))
-    (import "c" (value $v2 string))
-    (start $f (value $v) (value $v2) (result (value $c)))
-    (export "a" (value $c))
-  )
-  "component start function has a result count of 1 but the function type has a result count of 2"
-)
-
-(assert_invalid
-  (component
-    (import "a" (func (result "foo" string) (result s32) (result "bar" u32)))
-  )
-  "function result name cannot be empty"
-)
-
-(assert_invalid
-  (component
-    (type (func (result "FOO" string) (result "foo" u32)))
-  )
-  "function result name `foo` conflicts with previous result name `FOO`"
-)
diff --git a/tests/local/component-model/naming.wast b/tests/local/component-model/naming.wast
index 34756d29..8372821a 100644
--- a/tests/local/component-model/naming.wast
+++ b/tests/local/component-model/naming.wast
@@ -56,13 +56,6 @@
   "function parameter name `yOu` is not in kebab case"
 )
 
-(assert_invalid
-  (component
-    (type (func (result "uP" string)))
-  )
-  "name `uP` is not in kebab case"
-)
-
 (assert_invalid
   (component
     (type (component (export "NevEr" (func))))
diff --git a/tests/local/component-model/resources.wast b/tests/local/component-model/resources.wast
index 99398081..ef9a4224 100644
--- a/tests/local/component-model/resources.wast
+++ b/tests/local/component-model/resources.wast
@@ -179,10 +179,10 @@
   (type (component
     (import "x" (instance $i
       (export $t "t" (type (sub resource)))
-      (export "f" (func (result "x" (own $t))))
+      (export "f" (func (result (own $t))))
     ))
     (alias export $i "t" (type $t))
-    (export "f" (func (result "x" (own $t))))
+    (export "f" (func (result (own $t))))
   ))
 )
 
diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs
index d1478d10..841a76fd 100644
--- a/tests/roundtrip.rs
+++ b/tests/roundtrip.rs
@@ -621,8 +621,6 @@ impl TestState {
             & !WasmFeatures::SHARED_EVERYTHING_THREADS
             & !WasmFeatures::COMPONENT_MODEL
             & !WasmFeatures::COMPONENT_MODEL_NESTED_NAMES
-            & !WasmFeatures::COMPONENT_MODEL_MORE_FLAGS
-            & !WasmFeatures::COMPONENT_MODEL_MULTIPLE_RETURNS
             & !WasmFeatures::LEGACY_EXCEPTIONS;
         for part in test.iter().filter_map(|t| t.to_str()) {
             match part {
@@ -669,12 +667,6 @@ impl TestState {
                 "import-extended.wast" => {
                     features.insert(WasmFeatures::COMPONENT_MODEL_NESTED_NAMES);
                 }
-                "more-flags.wast" => {
-                    features.insert(WasmFeatures::COMPONENT_MODEL_MORE_FLAGS);
-                }
-                "multiple-returns.wast" => {
-                    features.insert(WasmFeatures::COMPONENT_MODEL_MULTIPLE_RETURNS);
-                }
                 "stack-switching" => {
                     features.insert(WasmFeatures::STACK_SWITCHING);
                 }
diff --git a/tests/snapshots/local/component-model/func.wast.json b/tests/snapshots/local/component-model/func.wast.json
index 859e07ed..7a1ae462 100644
--- a/tests/snapshots/local/component-model/func.wast.json
+++ b/tests/snapshots/local/component-model/func.wast.json
@@ -7,71 +7,78 @@
       "filename": "func.0.wasm",
       "module_type": "binary"
     },
-    {
-      "type": "assert_invalid",
-      "line": 8,
-      "filename": "func.1.wasm",
-      "module_type": "binary",
-      "text": "multiple returns on a function is now a gated feature"
-    },
     {
       "type": "module",
-      "line": 13,
-      "filename": "func.2.wasm",
+      "line": 7,
+      "filename": "func.1.wasm",
       "module_type": "binary"
     },
     {
       "type": "assert_invalid",
-      "line": 22,
-      "filename": "func.3.wasm",
+      "line": 16,
+      "filename": "func.2.wasm",
       "module_type": "binary",
       "text": "function parameter name `FOO` conflicts with previous parameter name `foo`"
     },
     {
       "type": "assert_invalid",
-      "line": 30,
-      "filename": "func.4.wasm",
+      "line": 23,
+      "filename": "func.3.wasm",
       "module_type": "binary",
       "text": "canonical option `memory` is required"
     },
     {
       "type": "module",
-      "line": 44,
+      "line": 37,
+      "filename": "func.4.wasm",
+      "module_type": "binary"
+    },
+    {
+      "type": "module",
+      "line": 46,
       "filename": "func.5.wasm",
       "module_type": "binary"
     },
     {
       "type": "module",
-      "line": 53,
+      "line": 58,
       "filename": "func.6.wasm",
       "module_type": "binary"
     },
     {
-      "type": "module",
-      "line": 65,
+      "type": "assert_invalid",
+      "line": 75,
       "filename": "func.7.wasm",
-      "module_type": "binary"
+      "module_type": "binary",
+      "text": "canonical option `realloc` is required"
     },
     {
       "type": "assert_invalid",
-      "line": 82,
+      "line": 98,
       "filename": "func.8.wasm",
       "module_type": "binary",
       "text": "canonical option `realloc` is required"
     },
     {
       "type": "assert_invalid",
-      "line": 105,
+      "line": 110,
       "filename": "func.9.wasm",
       "module_type": "binary",
       "text": "canonical option `realloc` is required"
     },
     {
       "type": "assert_invalid",
-      "line": 117,
+      "line": 125,
       "filename": "func.10.wasm",
       "module_type": "binary",
-      "text": "canonical option `realloc` is required"
+      "text": "invalid leading byte (0x1) for number of results"
+    },
+    {
+      "type": "assert_invalid",
+      "line": 136,
+      "filename": "func.11.wasm",
+      "module_type": "binary",
+      "text": "invalid leading byte (0x2) for component function results"
     }
   ]
 }
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/func.wast/0.print b/tests/snapshots/local/component-model/func.wast/0.print
index 4613ae24..25cfefaf 100644
--- a/tests/snapshots/local/component-model/func.wast/0.print
+++ b/tests/snapshots/local/component-model/func.wast/0.print
@@ -4,6 +4,6 @@
   (type (;1;) (func (param "foo" string) (param "bar" s32) (param "baz" u32)))
   (import "b" (func (;1;) (type 1)))
   (type (;2;) (tuple u8))
-  (type (;3;) (func (result "foo" 2)))
+  (type (;3;) (func (result 2)))
   (import "c" (func (;2;) (type 3)))
 )
diff --git a/tests/snapshots/local/component-model/func.wast/2.print b/tests/snapshots/local/component-model/func.wast/1.print
similarity index 100%
rename from tests/snapshots/local/component-model/func.wast/2.print
rename to tests/snapshots/local/component-model/func.wast/1.print
diff --git a/tests/snapshots/local/component-model/func.wast/4.print b/tests/snapshots/local/component-model/func.wast/4.print
new file mode 100644
index 00000000..89724839
--- /dev/null
+++ b/tests/snapshots/local/component-model/func.wast/4.print
@@ -0,0 +1,11 @@
+(component
+  (type (;0;) (func (param "msg" string)))
+  (import "a" (func $log (;0;) (type 0)))
+  (core module $libc (;0;)
+    (memory (;0;) 1)
+    (export "memory" (memory 0))
+  )
+  (core instance $libc (;0;) (instantiate $libc))
+  (alias core export $libc "memory" (core memory (;0;)))
+  (core func (;0;) (canon lower (func $log) (memory 0)))
+)
diff --git a/tests/snapshots/local/component-model/func.wast/5.print b/tests/snapshots/local/component-model/func.wast/5.print
index 89724839..6fb511ce 100644
--- a/tests/snapshots/local/component-model/func.wast/5.print
+++ b/tests/snapshots/local/component-model/func.wast/5.print
@@ -1,11 +1,18 @@
 (component
-  (type (;0;) (func (param "msg" string)))
-  (import "a" (func $log (;0;) (type 0)))
-  (core module $libc (;0;)
+  (core module $m (;0;)
+    (type (;0;) (func (result i32)))
     (memory (;0;) 1)
     (export "memory" (memory 0))
+    (export "ret-list" (func 0))
+    (func (;0;) (type 0) (result i32)
+      unreachable
+    )
   )
-  (core instance $libc (;0;) (instantiate $libc))
-  (alias core export $libc "memory" (core memory (;0;)))
-  (core func (;0;) (canon lower (func $log) (memory 0)))
+  (core instance $i (;0;) (instantiate $m))
+  (type (;0;) (list u8))
+  (type (;1;) (func (result 0)))
+  (alias core export $i "ret-list" (core func (;0;)))
+  (alias core export $i "memory" (core memory (;0;)))
+  (func (;0;) (type 1) (canon lift (core func 0) (memory 0)))
+  (export (;1;) "ret-list" (func 0))
 )
diff --git a/tests/snapshots/local/component-model/func.wast/6.print b/tests/snapshots/local/component-model/func.wast/6.print
index 6fb511ce..0fb8bfe3 100644
--- a/tests/snapshots/local/component-model/func.wast/6.print
+++ b/tests/snapshots/local/component-model/func.wast/6.print
@@ -1,18 +1,14 @@
 (component
-  (core module $m (;0;)
-    (type (;0;) (func (result i32)))
-    (memory (;0;) 1)
-    (export "memory" (memory 0))
-    (export "ret-list" (func 0))
-    (func (;0;) (type 0) (result i32)
-      unreachable
+  (type $big (;0;) (func (param "p1" u32) (param "p2" u32) (param "p3" u32) (param "p4" u32) (param "p5" u32) (param "p6" u32) (param "p7" u32) (param "p8" u32) (param "p9" u32) (param "p10" u32) (param "p11" u32) (param "p12" u32) (param "p13" u32) (param "p14" u32) (param "p15" u32) (param "p16" u32) (param "p17" u32) (param "p18" u32) (param "p19" u32) (param "p20" u32)))
+  (component $c (;0;)
+    (alias outer 1 $big (type $big (;0;)))
+    (import "big" (func $big (;0;) (type $big)))
+    (core module $libc (;0;)
+      (memory (;0;) 1)
+      (export "memory" (memory 0))
     )
+    (core instance $libc (;0;) (instantiate $libc))
+    (alias core export $libc "memory" (core memory (;0;)))
+    (core func $big (;0;) (canon lower (func $big) (memory 0)))
   )
-  (core instance $i (;0;) (instantiate $m))
-  (type (;0;) (list u8))
-  (type (;1;) (func (result 0)))
-  (alias core export $i "ret-list" (core func (;0;)))
-  (alias core export $i "memory" (core memory (;0;)))
-  (func (;0;) (type 1) (canon lift (core func 0) (memory 0)))
-  (export (;1;) "ret-list" (func 0))
 )
diff --git a/tests/snapshots/local/component-model/func.wast/7.print b/tests/snapshots/local/component-model/func.wast/7.print
deleted file mode 100644
index 0fb8bfe3..00000000
--- a/tests/snapshots/local/component-model/func.wast/7.print
+++ /dev/null
@@ -1,14 +0,0 @@
-(component
-  (type $big (;0;) (func (param "p1" u32) (param "p2" u32) (param "p3" u32) (param "p4" u32) (param "p5" u32) (param "p6" u32) (param "p7" u32) (param "p8" u32) (param "p9" u32) (param "p10" u32) (param "p11" u32) (param "p12" u32) (param "p13" u32) (param "p14" u32) (param "p15" u32) (param "p16" u32) (param "p17" u32) (param "p18" u32) (param "p19" u32) (param "p20" u32)))
-  (component $c (;0;)
-    (alias outer 1 $big (type $big (;0;)))
-    (import "big" (func $big (;0;) (type $big)))
-    (core module $libc (;0;)
-      (memory (;0;) 1)
-      (export "memory" (memory 0))
-    )
-    (core instance $libc (;0;) (instantiate $libc))
-    (alias core export $libc "memory" (core memory (;0;)))
-    (core func $big (;0;) (canon lower (func $big) (memory 0)))
-  )
-)
diff --git a/tests/snapshots/local/component-model/instantiate.wast.json b/tests/snapshots/local/component-model/instantiate.wast.json
index 053645d8..0aea2c08 100644
--- a/tests/snapshots/local/component-model/instantiate.wast.json
+++ b/tests/snapshots/local/component-model/instantiate.wast.json
@@ -120,7 +120,7 @@
       "line": 181,
       "filename": "instantiate.18.wasm",
       "module_type": "binary",
-      "text": "expected 0 results, found 1"
+      "text": "expected a result, found none"
     },
     {
       "type": "assert_invalid",
@@ -482,166 +482,159 @@
       "line": 710,
       "filename": "instantiate.71.wasm",
       "module_type": "binary",
-      "text": "mismatched result names"
-    },
-    {
-      "type": "assert_invalid",
-      "line": 720,
-      "filename": "instantiate.72.wasm",
-      "module_type": "binary",
       "text": "type mismatch with result type"
     },
     {
       "type": "assert_invalid",
-      "line": 731,
-      "filename": "instantiate.73.wasm",
+      "line": 721,
+      "filename": "instantiate.72.wasm",
       "module_type": "binary",
       "text": "type mismatch in instance export `a`"
     },
     {
       "type": "assert_invalid",
-      "line": 742,
-      "filename": "instantiate.74.wasm",
+      "line": 732,
+      "filename": "instantiate.73.wasm",
       "module_type": "binary",
       "text": "expected primitive, found record"
     },
     {
       "type": "assert_invalid",
-      "line": 754,
-      "filename": "instantiate.75.wasm",
+      "line": 744,
+      "filename": "instantiate.74.wasm",
       "module_type": "binary",
       "text": "expected record, found u32"
     },
     {
       "type": "assert_invalid",
-      "line": 766,
-      "filename": "instantiate.76.wasm",
+      "line": 756,
+      "filename": "instantiate.75.wasm",
       "module_type": "binary",
       "text": "expected u32, found tuple"
     },
     {
       "type": "assert_invalid",
-      "line": 779,
-      "filename": "instantiate.77.wasm",
+      "line": 769,
+      "filename": "instantiate.76.wasm",
       "module_type": "binary",
       "text": "type mismatch in record field `x`"
     },
     {
       "type": "assert_invalid",
-      "line": 792,
-      "filename": "instantiate.78.wasm",
+      "line": 782,
+      "filename": "instantiate.77.wasm",
       "module_type": "binary",
       "text": "expected 1 fields, found 2"
     },
     {
       "type": "assert_invalid",
-      "line": 804,
-      "filename": "instantiate.79.wasm",
+      "line": 794,
+      "filename": "instantiate.78.wasm",
       "module_type": "binary",
       "text": "expected field name `a`, found `b`"
     },
     {
       "type": "assert_invalid",
-      "line": 816,
-      "filename": "instantiate.80.wasm",
+      "line": 806,
+      "filename": "instantiate.79.wasm",
       "module_type": "binary",
       "text": "expected 1 cases, found 2"
     },
     {
       "type": "assert_invalid",
-      "line": 828,
-      "filename": "instantiate.81.wasm",
+      "line": 818,
+      "filename": "instantiate.80.wasm",
       "module_type": "binary",
       "text": "expected case named `x`, found `y`"
     },
     {
       "type": "assert_invalid",
-      "line": 840,
-      "filename": "instantiate.82.wasm",
+      "line": 830,
+      "filename": "instantiate.81.wasm",
       "module_type": "binary",
       "text": "expected case `x` to have a type, found none"
     },
     {
       "type": "assert_invalid",
-      "line": 852,
-      "filename": "instantiate.83.wasm",
+      "line": 842,
+      "filename": "instantiate.82.wasm",
       "module_type": "binary",
       "text": "expected case `x` to have no type"
     },
     {
       "type": "assert_invalid",
-      "line": 864,
-      "filename": "instantiate.84.wasm",
+      "line": 854,
+      "filename": "instantiate.83.wasm",
       "module_type": "binary",
       "text": "type mismatch in variant case `x`"
     },
     {
       "type": "assert_invalid",
-      "line": 876,
-      "filename": "instantiate.85.wasm",
+      "line": 866,
+      "filename": "instantiate.84.wasm",
       "module_type": "binary",
       "text": "expected 1 types, found 2"
     },
     {
       "type": "assert_invalid",
-      "line": 888,
-      "filename": "instantiate.86.wasm",
+      "line": 878,
+      "filename": "instantiate.85.wasm",
       "module_type": "binary",
       "text": "type mismatch in tuple field 0"
     },
     {
       "type": "assert_invalid",
-      "line": 900,
-      "filename": "instantiate.87.wasm",
+      "line": 890,
+      "filename": "instantiate.86.wasm",
       "module_type": "binary",
       "text": "mismatch in flags elements"
     },
     {
       "type": "assert_invalid",
-      "line": 912,
-      "filename": "instantiate.88.wasm",
+      "line": 902,
+      "filename": "instantiate.87.wasm",
       "module_type": "binary",
       "text": "mismatch in enum elements"
     },
     {
       "type": "assert_invalid",
-      "line": 924,
-      "filename": "instantiate.89.wasm",
+      "line": 914,
+      "filename": "instantiate.88.wasm",
       "module_type": "binary",
       "text": "type mismatch in ok variant"
     },
     {
       "type": "assert_invalid",
-      "line": 936,
-      "filename": "instantiate.90.wasm",
+      "line": 926,
+      "filename": "instantiate.89.wasm",
       "module_type": "binary",
       "text": "type mismatch in err variant"
     },
     {
       "type": "assert_invalid",
-      "line": 948,
-      "filename": "instantiate.91.wasm",
+      "line": 938,
+      "filename": "instantiate.90.wasm",
       "module_type": "binary",
       "text": "expected ok type to not be present"
     },
     {
       "type": "assert_invalid",
-      "line": 960,
-      "filename": "instantiate.92.wasm",
+      "line": 950,
+      "filename": "instantiate.91.wasm",
       "module_type": "binary",
       "text": "expected ok type, but found none"
     },
     {
       "type": "assert_invalid",
-      "line": 972,
-      "filename": "instantiate.93.wasm",
+      "line": 962,
+      "filename": "instantiate.92.wasm",
       "module_type": "binary",
       "text": "expected err type to not be present"
     },
     {
       "type": "assert_invalid",
-      "line": 984,
-      "filename": "instantiate.94.wasm",
+      "line": 974,
+      "filename": "instantiate.93.wasm",
       "module_type": "binary",
       "text": "expected err type, but found none"
     }
diff --git a/tests/snapshots/local/component-model/more-flags.wast.json b/tests/snapshots/local/component-model/more-flags.wast.json
index 0cf61b84..675d6286 100644
--- a/tests/snapshots/local/component-model/more-flags.wast.json
+++ b/tests/snapshots/local/component-model/more-flags.wast.json
@@ -2,10 +2,11 @@
   "source_filename": "tests/local/component-model/more-flags.wast",
   "commands": [
     {
-      "type": "module",
-      "line": 1,
+      "type": "assert_invalid",
+      "line": 2,
       "filename": "more-flags.0.wasm",
-      "module_type": "binary"
+      "module_type": "binary",
+      "text": "cannot have more than 32 flags"
     }
   ]
 }
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/more-flags.wast/0.print b/tests/snapshots/local/component-model/more-flags.wast/0.print
deleted file mode 100644
index 5e23480a..00000000
--- a/tests/snapshots/local/component-model/more-flags.wast/0.print
+++ /dev/null
@@ -1,3 +0,0 @@
-(component
-  (type (;0;) (flags "f1" "f2" "f3" "f4" "f5" "f6" "f7" "f8" "f9" "f10" "f11" "f12" "f13" "f14" "f15" "f16" "f17" "f18" "f19" "f20" "f21" "f22" "f23" "f24" "f25" "f26" "f27" "f28" "f29" "f30" "f31" "f32" "f33"))
-)
diff --git a/tests/snapshots/local/component-model/multiple-returns.wast.json b/tests/snapshots/local/component-model/multiple-returns.wast.json
deleted file mode 100644
index b9a6317b..00000000
--- a/tests/snapshots/local/component-model/multiple-returns.wast.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "source_filename": "tests/local/component-model/multiple-returns.wast",
-  "commands": [
-    {
-      "type": "module",
-      "line": 1,
-      "filename": "multiple-returns.0.wasm",
-      "module_type": "binary"
-    },
-    {
-      "type": "module",
-      "line": 5,
-      "filename": "multiple-returns.1.wasm",
-      "module_type": "binary"
-    },
-    {
-      "type": "assert_invalid",
-      "line": 15,
-      "filename": "multiple-returns.2.wasm",
-      "module_type": "binary",
-      "text": "component start function has a result count of 1 but the function type has a result count of 2"
-    },
-    {
-      "type": "assert_invalid",
-      "line": 26,
-      "filename": "multiple-returns.3.wasm",
-      "module_type": "binary",
-      "text": "function result name cannot be empty"
-    },
-    {
-      "type": "assert_invalid",
-      "line": 33,
-      "filename": "multiple-returns.4.wasm",
-      "module_type": "binary",
-      "text": "function result name `foo` conflicts with previous result name `FOO`"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/multiple-returns.wast/0.print b/tests/snapshots/local/component-model/multiple-returns.wast/0.print
deleted file mode 100644
index 5bb4d4dc..00000000
--- a/tests/snapshots/local/component-model/multiple-returns.wast/0.print
+++ /dev/null
@@ -1,4 +0,0 @@
-(component
-  (type (;0;) (func (result "foo" string) (result "bar" s32) (result "baz" u32)))
-  (import "a" (func (;0;) (type 0)))
-)
diff --git a/tests/snapshots/local/component-model/multiple-returns.wast/1.print b/tests/snapshots/local/component-model/multiple-returns.wast/1.print
deleted file mode 100644
index 4063bf72..00000000
--- a/tests/snapshots/local/component-model/multiple-returns.wast/1.print
+++ /dev/null
@@ -1,9 +0,0 @@
-(component
-  (type (;0;) (func (param "a" string) (param "b" string) (result "c" s32) (result "d" s32)))
-  (import "a" (func $f (;0;) (type 0)))
-  (import "b" (value $v (;0;) string))
-  (import "c" (value $v2 (;1;) string))
-  (start $f (value $v) (value $v2) (result (value (;2;))) (result (value (;3;))))
-  (export (;4;) "d" (value 2))
-  (export (;5;) "e" (value 3))
-)
diff --git a/tests/snapshots/local/component-model/naming.wast.json b/tests/snapshots/local/component-model/naming.wast.json
index c4e0b07d..72aafda9 100644
--- a/tests/snapshots/local/component-model/naming.wast.json
+++ b/tests/snapshots/local/component-model/naming.wast.json
@@ -61,61 +61,54 @@
       "line": 60,
       "filename": "naming.8.wasm",
       "module_type": "binary",
-      "text": "name `uP` is not in kebab case"
+      "text": "`NevEr` is not in kebab case"
     },
     {
       "type": "assert_invalid",
       "line": 67,
       "filename": "naming.9.wasm",
       "module_type": "binary",
-      "text": "`NevEr` is not in kebab case"
+      "text": "`GonnA` is not in kebab case"
     },
     {
       "type": "assert_invalid",
       "line": 74,
       "filename": "naming.10.wasm",
       "module_type": "binary",
-      "text": "`GonnA` is not in kebab case"
+      "text": "`lET` is not in kebab case"
     },
     {
       "type": "assert_invalid",
       "line": 81,
       "filename": "naming.11.wasm",
       "module_type": "binary",
-      "text": "`lET` is not in kebab case"
+      "text": "`YoU` is not in kebab case"
     },
     {
       "type": "assert_invalid",
       "line": 88,
       "filename": "naming.12.wasm",
       "module_type": "binary",
-      "text": "`YoU` is not in kebab case"
+      "text": "`DOWn` is not in kebab case"
     },
     {
       "type": "assert_invalid",
       "line": 95,
       "filename": "naming.13.wasm",
       "module_type": "binary",
-      "text": "`DOWn` is not in kebab case"
-    },
-    {
-      "type": "assert_invalid",
-      "line": 102,
-      "filename": "naming.14.wasm",
-      "module_type": "binary",
       "text": "character `A` is not lowercase in package name/namespace"
     },
     {
       "type": "assert_invalid",
-      "line": 108,
-      "filename": "naming.15.wasm",
+      "line": 101,
+      "filename": "naming.14.wasm",
       "module_type": "binary",
       "text": "character `B` is not lowercase in package name/namespace"
     },
     {
       "type": "module",
-      "line": 113,
-      "filename": "naming.16.wasm",
+      "line": 106,
+      "filename": "naming.15.wasm",
       "module_type": "binary"
     }
   ]
diff --git a/tests/snapshots/local/component-model/naming.wast/16.print b/tests/snapshots/local/component-model/naming.wast/15.print
similarity index 100%
rename from tests/snapshots/local/component-model/naming.wast/16.print
rename to tests/snapshots/local/component-model/naming.wast/15.print
diff --git a/tests/snapshots/local/component-model/resources.wast/22.print b/tests/snapshots/local/component-model/resources.wast/22.print
index 42945188..4cbded7a 100644
--- a/tests/snapshots/local/component-model/resources.wast/22.print
+++ b/tests/snapshots/local/component-model/resources.wast/22.print
@@ -5,14 +5,14 @@
         (instance
           (export (;0;) "t" (type (sub resource)))
           (type (;1;) (own 0))
-          (type (;2;) (func (result "x" 1)))
+          (type (;2;) (func (result 1)))
           (export (;0;) "f" (func (type 2)))
         )
       )
       (import "x" (instance (;0;) (type 0)))
       (alias export 0 "t" (type (;1;)))
       (type (;2;) (own 1))
-      (type (;3;) (func (result "x" 2)))
+      (type (;3;) (func (result 2)))
       (export (;0;) "f" (func (type 3)))
     )
   )