From 6be3b47fbe0c1d92dbbd3bd85fe2a92aebbbdb7e Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Fri, 25 Aug 2023 10:49:24 -0400 Subject: [PATCH] Remove component union types - Bump wasm-tools deps - Use new TypeSectionReader::into_iter_err_on_gc_types method --- Cargo.lock | 123 +++++++++--------- Cargo.toml | 21 +-- cranelift/wasm/src/sections_translator.rs | 24 +--- crates/component-macro/src/component.rs | 24 ---- .../component-macro/tests/codegen/unions.wit | 66 ---------- .../tests/codegen/variants.wit | 11 -- .../fuzz/fuzz_targets/fact-valid-module.rs | 2 +- crates/environ/src/component/types.rs | 54 -------- crates/environ/src/fact/trampoline.rs | 44 +------ crates/environ/src/module_environ.rs | 25 +--- .../fuzzing/src/generators/component_types.rs | 9 -- crates/misc/component-fuzz-util/src/lib.rs | 44 +------ crates/wasmtime/src/component/func/typed.rs | 29 ----- crates/wasmtime/src/component/mod.rs | 8 +- crates/wasmtime/src/component/types.rs | 41 +----- crates/wasmtime/src/component/values.rs | 104 --------------- crates/wast/src/component.rs | 22 ---- crates/wit-bindgen/src/lib.rs | 11 -- crates/wit-bindgen/src/rust.rs | 119 ----------------- crates/wit-bindgen/src/types.rs | 5 - tests/all/component_model/dynamic.rs | 11 +- tests/all/component_model/macros.rs | 88 ------------- .../misc_testsuite/component-model/types.wast | 2 +- 23 files changed, 100 insertions(+), 787 deletions(-) delete mode 100644 crates/component-macro/tests/codegen/unions.wit diff --git a/Cargo.lock b/Cargo.lock index dbd23f150cbb..16e6596c8e9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,7 +656,7 @@ dependencies = [ "target-lexicon", "thiserror", "toml", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wat", ] @@ -833,7 +833,7 @@ dependencies = [ "serde", "smallvec", "target-lexicon", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmtime-types", "wat", ] @@ -2691,7 +2691,7 @@ dependencies = [ "wasmtime", "wasmtime-wasi", "wasmtime-wasi-http", - "wit-component 0.13.2", + "wit-component 0.14.0", ] [[package]] @@ -2967,7 +2967,7 @@ name = "verify-component-adapter" version = "13.0.0" dependencies = [ "anyhow", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wat", ] @@ -3069,7 +3069,7 @@ dependencies = [ "byte-array-literals", "object", "wasi", - "wasm-encoder 0.31.1", + "wasm-encoder 0.32.0", "wit-bindgen", ] @@ -3172,9 +3172,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41763f20eafed1399fff1afb466496d3a959f58241436cfdc17e3f5ca954de16" +checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" dependencies = [ "leb128", ] @@ -3196,45 +3196,45 @@ dependencies = [ [[package]] name = "wasm-metadata" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ac8d3bcbbb5081489f35966b86d127596e9cdacfb3824b79f43344662226178" +checksum = "08dc59d1fa569150851542143ca79438ca56845ccb31696c70225c638e063471" dependencies = [ "anyhow", "indexmap 2.0.0", "serde", "serde_json", "spdx", - "wasm-encoder 0.31.1", - "wasmparser 0.111.0", + "wasm-encoder 0.32.0", + "wasmparser 0.112.0", ] [[package]] name = "wasm-mutate" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ff8dc1c451e485af2fdd3997acb95dde3a99ecb584cc0c23c25d0f857a64b1" +checksum = "1a893c0b2bad91ea78171dbff7fe6d764f8b1c9e20617061d284cfbdf902e329" dependencies = [ "egg", "log", "rand", "thiserror", - "wasm-encoder 0.31.1", - "wasmparser 0.111.0", + "wasm-encoder 0.32.0", + "wasmparser 0.112.0", ] [[package]] name = "wasm-smith" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07a8af736893cab6d785987ffb6abec45d30b19e64eb7ea022425120354e557e" +checksum = "ad8e84473dc3e1ca4759114ba8f3beaf3b7272d67868e351ba5d3fc006139f93" dependencies = [ "arbitrary", "flagset", "indexmap 2.0.0", "leb128", - "wasm-encoder 0.31.1", - "wasmparser 0.111.0", + "wasm-encoder 0.32.0", + "wasmparser 0.112.0", ] [[package]] @@ -3287,9 +3287,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.111.0" +version = "0.112.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad71036aada3f6b09251546e97e4f4f176dd6b41cf6fa55e7e0f65e86aec319a" +checksum = "e986b010f47fcce49cf8ea5d5f9e5d2737832f12b53ae8ae785bbe895d0877bf" dependencies = [ "indexmap 2.0.0", "semver", @@ -3306,12 +3306,12 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.2.63" +version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb8cc41d341939dce08ee902b50e36cd35add940f6044c94b144e8f73fe07a6" +checksum = "34ddf5892036cd4b780d505eff1194a0cbc10ed896097656fdcea3744b5e7c2f" dependencies = [ "anyhow", - "wasmparser 0.111.0", + "wasmparser 0.112.0", ] [[package]] @@ -3338,8 +3338,8 @@ dependencies = [ "target-lexicon", "tempfile", "wasi-cap-std-sync", - "wasm-encoder 0.31.1", - "wasmparser 0.111.0", + "wasm-encoder 0.32.0", + "wasmparser 0.112.0", "wasmtime-cache", "wasmtime-component-macro", "wasmtime-component-util", @@ -3452,8 +3452,8 @@ dependencies = [ "test-programs", "tokio", "walkdir", - "wasm-encoder 0.31.1", - "wasmparser 0.111.0", + "wasm-encoder 0.32.0", + "wasmparser 0.112.0", "wasmtime", "wasmtime-cache", "wasmtime-cli-flags", @@ -3467,7 +3467,7 @@ dependencies = [ "wasmtime-wasi-nn", "wasmtime-wasi-threads", "wasmtime-wast", - "wast 63.0.0", + "wast 64.0.0", "wat", "windows-sys", ] @@ -3497,7 +3497,7 @@ dependencies = [ "wasmtime", "wasmtime-component-util", "wasmtime-wit-bindgen", - "wit-parser 0.10.0", + "wit-parser 0.11.0", ] [[package]] @@ -3521,7 +3521,7 @@ dependencies = [ "object", "target-lexicon", "thiserror", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmtime-cranelift-shared", "wasmtime-environ", "wasmtime-versioned-export-macros", @@ -3557,8 +3557,8 @@ dependencies = [ "serde", "target-lexicon", "thiserror", - "wasm-encoder 0.31.1", - "wasmparser 0.111.0", + "wasm-encoder 0.32.0", + "wasmparser 0.112.0", "wasmprinter", "wasmtime-component-util", "wasmtime-types", @@ -3573,7 +3573,7 @@ dependencies = [ "component-fuzz-util", "env_logger 0.10.0", "libfuzzer-sys", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmprinter", "wasmtime-environ", "wat", @@ -3628,7 +3628,7 @@ dependencies = [ "rand", "smallvec", "target-lexicon", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmtime", "wasmtime-fuzzing", ] @@ -3648,12 +3648,12 @@ dependencies = [ "target-lexicon", "tempfile", "v8", - "wasm-encoder 0.31.1", + "wasm-encoder 0.32.0", "wasm-mutate", "wasm-smith", "wasm-spec-interpreter", "wasmi", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmprinter", "wasmtime", "wasmtime-wast", @@ -3722,7 +3722,7 @@ dependencies = [ "rand", "rustix 0.38.8", "sptr", - "wasm-encoder 0.31.1", + "wasm-encoder 0.32.0", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-fiber", @@ -3739,7 +3739,7 @@ dependencies = [ "cranelift-entity", "serde", "thiserror", - "wasmparser 0.111.0", + "wasmparser 0.112.0", ] [[package]] @@ -3837,7 +3837,7 @@ dependencies = [ "anyhow", "log", "wasmtime", - "wast 63.0.0", + "wast 64.0.0", ] [[package]] @@ -3849,7 +3849,7 @@ dependencies = [ "gimli", "object", "target-lexicon", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmtime-cranelift-shared", "wasmtime-environ", "winch-codegen", @@ -3862,7 +3862,7 @@ dependencies = [ "anyhow", "heck", "indexmap 2.0.0", - "wit-parser 0.10.0", + "wit-parser 0.11.0", ] [[package]] @@ -3880,23 +3880,23 @@ dependencies = [ [[package]] name = "wast" -version = "63.0.0" +version = "64.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2560471f60a48b77fccefaf40796fda61c97ce1e790b59dfcec9dc3995c9f63a" +checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" dependencies = [ "leb128", "memchr", "unicode-width", - "wasm-encoder 0.31.1", + "wasm-encoder 0.32.0", ] [[package]] name = "wat" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdc306c2c4c2f2bf2ba69e083731d0d2a77437fc6a350a19db139636e7e416c" +checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" dependencies = [ - "wast 63.0.0", + "wast 64.0.0", ] [[package]] @@ -4021,7 +4021,7 @@ dependencies = [ "regalloc2", "smallvec", "target-lexicon", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmtime-environ", ] @@ -4065,7 +4065,7 @@ dependencies = [ "similar", "target-lexicon", "toml", - "wasmparser 0.111.0", + "wasmparser 0.112.0", "wasmtime-environ", "wat", "winch-codegen", @@ -4226,18 +4226,20 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9eb6179c5a26adc38fa5a22e263e7a3812c6777ca2e75d1717fd3789f82b64" +checksum = "66d9f2d16dd55d1a372dcfd4b7a466ea876682a5a3cb97e71ec9eef04affa876" dependencies = [ "anyhow", "bitflags 2.3.3", "indexmap 2.0.0", "log", - "wasm-encoder 0.31.1", - "wasm-metadata 0.10.2", - "wasmparser 0.111.0", - "wit-parser 0.10.0", + "serde", + "serde_json", + "wasm-encoder 0.32.0", + "wasm-metadata 0.10.3", + "wasmparser 0.112.0", + "wit-parser 0.11.0", ] [[package]] @@ -4258,9 +4260,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d6926af931f285e206ea71f9b67681f00a65d79097f81da7f9f285de006ba2" +checksum = "61e8b849bea13cc2315426b16efe6eb6813466d78f5fde69b0bb150c9c40e0dc" dependencies = [ "anyhow", "id-arena", @@ -4311,3 +4313,8 @@ dependencies = [ "cc", "libc", ] + +[[patch.unused]] +name = "wit-bindgen" +version = "0.10.0" +source = "git+https://github.com/lann/wit-bindgen.git?branch=remove-union#aa7c6f783de60bb71266f7a7b85e45b81f981da6" diff --git a/Cargo.toml b/Cargo.toml index d0838f2e7d94..50181c5409c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -205,15 +205,15 @@ is-terminal = "0.4.0" wit-bindgen = { version = "0.9.0", default-features = false } # wasm-tools family: -wasmparser = "0.111.0" -wat = "1.0.70" -wast = "63.0.0" -wasmprinter = "0.2.63" -wasm-encoder = "0.31.1" -wasm-smith = "0.12.14" -wasm-mutate = "0.2.31" -wit-parser = "0.10.0" -wit-component = "0.13.2" +wasmparser = "0.112.0" +wat = "1.0.71" +wast = "64.0.0" +wasmprinter = "0.2.64" +wasm-encoder = "0.32.0" +wasm-smith = "0.12.15" +wasm-mutate = "0.2.32" +wit-parser = "0.11.0" +wit-component = "0.14.0" # Non-Bytecode Alliance maintained dependencies: # -------------------------- @@ -321,3 +321,6 @@ debug-assertions = false # Omit integer overflow checks, which include failure messages which require # string initializers. overflow-checks = false + +[patch.crates-io] +wit-bindgen = { git = "https://github.com/lann/wit-bindgen.git", branch = "remove-union" } diff --git a/cranelift/wasm/src/sections_translator.rs b/cranelift/wasm/src/sections_translator.rs index 5037625767d0..e38b1327787b 100644 --- a/cranelift/wasm/src/sections_translator.rs +++ b/cranelift/wasm/src/sections_translator.rs @@ -21,8 +21,7 @@ use wasmparser::{ self, Data, DataKind, DataSectionReader, Element, ElementItems, ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, - Naming, Operator, StructuralType, TableSectionReader, TagSectionReader, TagType, TypeRef, - TypeSectionReader, + Naming, Operator, TableSectionReader, TagSectionReader, TagType, TypeRef, TypeSectionReader, }; fn memory(ty: MemoryType) -> Memory { @@ -50,24 +49,9 @@ pub fn parse_type_section<'a>( let count = types.count(); environ.reserve_types(count)?; - for entry in types { - let entry = entry?; - if entry.types().len() != 1 { - unimplemented!("gc proposal"); - } - let entry = entry.types().first().unwrap(); - if entry.is_final || entry.supertype_idx.is_some() { - unimplemented!("gc proposal"); - } - match &entry.structural_type { - StructuralType::Func(wasm_func_ty) => { - let ty = environ.convert_func_type(&wasm_func_ty); - environ.declare_type_func(ty)?; - } - StructuralType::Array(_) | StructuralType::Struct(_) => { - unimplemented!("gc proposal"); - } - } + for ty in types.into_iter_err_on_gc_types() { + let ty = environ.convert_func_type(&ty?); + environ.declare_type_func(ty)?; } Ok(()) } diff --git a/crates/component-macro/src/component.rs b/crates/component-macro/src/component.rs index 0d63ec874cbf..0f49ef07a819 100644 --- a/crates/component-macro/src/component.rs +++ b/crates/component-macro/src/component.rs @@ -18,7 +18,6 @@ mod kw { pub enum VariantStyle { Variant, Enum, - Union, } impl fmt::Display for VariantStyle { @@ -26,7 +25,6 @@ impl fmt::Display for VariantStyle { f.write_str(match self { Self::Variant => "variant", Self::Enum => "enum", - Self::Union => "union", }) } } @@ -70,9 +68,6 @@ impl Parse for Style { } else if lookahead.peek(Token![enum]) { input.parse::()?; Ok(Style::Variant(VariantStyle::Enum)) - } else if lookahead.peek(Token![union]) { - input.parse::()?; - Ok(Style::Variant(VariantStyle::Union)) } else if input.peek(kw::flags) { Err(input.error( "`flags` not allowed here; \ @@ -238,7 +233,6 @@ fn expand_variant( match style { VariantStyle::Variant => "at most one unnamed field each", VariantStyle::Enum => "no fields", - VariantStyle::Union => "exactly one unnamed field each", } ), )) @@ -443,7 +437,6 @@ impl Expander for LiftExpander { let interface_type_variant = match style { VariantStyle::Variant => quote!(Variant), VariantStyle::Enum => quote!(Enum), - VariantStyle::Union => quote!(Union), }; for (index, VariantCase { ident, ty, .. }) in cases.iter().enumerate() { @@ -456,7 +449,6 @@ impl Expander for LiftExpander { VariantStyle::Variant => { quote!(ty.cases[#index].ty.unwrap_or_else(#internal::bad_type_info)) } - VariantStyle::Union => quote!(ty.types[#index]), VariantStyle::Enum => unreachable!(), }; lifts.extend( @@ -618,7 +610,6 @@ impl Expander for LowerExpander { let interface_type_variant = match style { VariantStyle::Variant => quote!(Variant), VariantStyle::Enum => quote!(Enum), - VariantStyle::Union => quote!(Union), }; for (index, VariantCase { ident, ty, .. }) in cases.iter().enumerate() { @@ -637,7 +628,6 @@ impl Expander for LowerExpander { VariantStyle::Variant => { quote!(ty.cases[#index].ty.unwrap_or_else(#internal::bad_type_info)) } - VariantStyle::Union => quote!(ty.types[#index]), VariantStyle::Enum => unreachable!(), }; pattern = quote!(Self::#ident(value)); @@ -768,13 +758,6 @@ impl Expander for ComponentTypeExpander { for (index, VariantCase { attrs, ident, ty }) in cases.iter().enumerate() { let rename = find_rename(attrs)?; - if let (Some(_), VariantStyle::Union) = (&rename, style) { - return Err(Error::new( - ident.span(), - "renaming `union` cases is not permitted; only the type is used", - )); - } - let name = rename.unwrap_or_else(|| syn::LitStr::new(&ident.to_string(), ident.span())); if let Some(ty) = ty { @@ -784,9 +767,6 @@ impl Expander for ComponentTypeExpander { VariantStyle::Variant => { quote!((#name, Some(<#ty as wasmtime::component::ComponentType>::typecheck)),) } - VariantStyle::Union => { - quote!(<#ty as wasmtime::component::ComponentType>::typecheck,) - } VariantStyle::Enum => { return Err(Error::new( ident.span(), @@ -810,9 +790,6 @@ impl Expander for ComponentTypeExpander { VariantStyle::Variant => { quote!((#name, None),) } - VariantStyle::Union => { - quote!(<() as wasmtime::component::ComponentType>::typecheck,) - } VariantStyle::Enum => quote!(#name,), }); lower_payload_case_declarations.extend(quote!(#ident: [wasmtime::ValRaw; 0],)); @@ -821,7 +798,6 @@ impl Expander for ComponentTypeExpander { let typecheck = match style { VariantStyle::Variant => quote!(typecheck_variant), - VariantStyle::Union => quote!(typecheck_union), VariantStyle::Enum => quote!(typecheck_enum), }; diff --git a/crates/component-macro/tests/codegen/unions.wit b/crates/component-macro/tests/codegen/unions.wit deleted file mode 100644 index 252f513f2de8..000000000000 --- a/crates/component-macro/tests/codegen/unions.wit +++ /dev/null @@ -1,66 +0,0 @@ -package foo:foo - -interface unions { - /// A union of all of the integral types - union all-integers { - /// Bool is equivalent to a 1 bit integer - /// and is treated that way in some languages - bool, - u8, u16, u32, u64, - s8, s16, s32, s64 - } - union all-floats { - float32, float64 - } - union all-text { - char, string - } - - // Returns the same case as the input but with 1 added - add-one-integer: func(num: all-integers) -> all-integers - // Returns the same case as the input but with 1 added - add-one-float: func(num: all-floats) -> all-floats - // Returns the same case as the input but with the first character replaced - replace-first-char: func(text: all-text, letter: char) -> all-text - - // Returns the index of the case provided - identify-integer: func(num: all-integers) -> u8 - // Returns the index of the case provided - identify-float: func(num: all-floats) -> u8 - // Returns the index of the case provided - identify-text: func(text: all-text) -> u8 - - union duplicated-s32 { - /// The first s32 - s32, - /// The second s32 - s32, - /// The third s32 - s32 - } - - // Returns the same case as the input but with 1 added - add-one-duplicated: func(num: duplicated-s32) -> duplicated-s32 - - // Returns the index of the case provided - identify-duplicated: func(num: duplicated-s32) -> u8 - - /// A type containing numeric types that are distinct in most languages - union distinguishable-num { - /// A Floating Point Number - float64, - /// A Signed Integer - s64 - } - - // Returns the same case as the input but with 1 added - add-one-distinguishable-num: func(num: distinguishable-num) -> distinguishable-num - - // Returns the index of the case provided - identify-distinguishable-num: func(num: distinguishable-num) -> u8 -} - -world the-unions { - import unions - export unions -} diff --git a/crates/component-macro/tests/codegen/variants.wit b/crates/component-macro/tests/codegen/variants.wit index b6c47d89650e..a53938cb02ef 100644 --- a/crates/component-macro/tests/codegen/variants.wit +++ b/crates/component-macro/tests/codegen/variants.wit @@ -8,19 +8,10 @@ interface variants { e1-arg: func(x: e1) e1-result: func() -> e1 - union u1 { - u32, - float32, - } - - u1-arg: func(x: u1) - u1-result: func() -> u1 - record empty {} variant v1 { a, - b(u1), c(e1), d(string), e(empty), @@ -40,7 +31,6 @@ interface variants { c: option, d: option, e: option, - f: option, g: option>, ) option-result: func() -> tuple< @@ -49,7 +39,6 @@ interface variants { option, option, option, - option, option>, > diff --git a/crates/environ/fuzz/fuzz_targets/fact-valid-module.rs b/crates/environ/fuzz/fuzz_targets/fact-valid-module.rs index b43f8cda6c90..f662d0c7e3bf 100644 --- a/crates/environ/fuzz/fuzz_targets/fact-valid-module.rs +++ b/crates/environ/fuzz/fuzz_targets/fact-valid-module.rs @@ -27,7 +27,7 @@ struct GenAdapter { post_return: bool, lift_memory64: bool, lower_memory64: bool, - test: TestCase, + test: TestCase<'static>, } fuzz_target!(|module: GenAdapterModule| { diff --git a/crates/environ/src/component/types.rs b/crates/environ/src/component/types.rs index ed262379e8df..18390b9fff83 100644 --- a/crates/environ/src/component/types.rs +++ b/crates/environ/src/component/types.rs @@ -100,8 +100,6 @@ indices! { pub struct TypeFlagsIndex(u32); /// Index pointing to an enum type in the component model. pub struct TypeEnumIndex(u32); - /// Index pointing to a union type in the component model. - pub struct TypeUnionIndex(u32); /// Index pointing to an option type in the component model (aka a /// `Option`) pub struct TypeOptionIndex(u32); @@ -252,7 +250,6 @@ pub struct ComponentTypes { tuples: PrimaryMap, enums: PrimaryMap, flags: PrimaryMap, - unions: PrimaryMap, options: PrimaryMap, results: PrimaryMap, resource_tables: PrimaryMap, @@ -293,7 +290,6 @@ impl ComponentTypes { InterfaceType::Tuple(i) => &self[*i].abi, InterfaceType::Flags(i) => &self[*i].abi, InterfaceType::Enum(i) => &self[*i].abi, - InterfaceType::Union(i) => &self[*i].abi, InterfaceType::Option(i) => &self[*i].abi, InterfaceType::Result(i) => &self[*i].abi, } @@ -340,7 +336,6 @@ impl_index! { impl Index for ComponentTypes { TypeTuple => tuples } impl Index for ComponentTypes { TypeEnum => enums } impl Index for ComponentTypes { TypeFlags => flags } - impl Index for ComponentTypes { TypeUnion => unions } impl Index for ComponentTypes { TypeOption => options } impl Index for ComponentTypes { TypeResult => results } impl Index for ComponentTypes { TypeList => lists } @@ -372,7 +367,6 @@ pub struct ComponentTypesBuilder { tuples: HashMap, enums: HashMap, flags: HashMap, - unions: HashMap, options: HashMap, results: HashMap, @@ -613,9 +607,6 @@ impl ComponentTypesBuilder { } types::ComponentDefinedType::Flags(e) => InterfaceType::Flags(self.flags_type(e)), types::ComponentDefinedType::Enum(e) => InterfaceType::Enum(self.enum_type(e)), - types::ComponentDefinedType::Union(e) => { - InterfaceType::Union(self.union_type(types, e)?) - } types::ComponentDefinedType::Option(e) => { InterfaceType::Option(self.option_type(types, e)?) } @@ -734,24 +725,6 @@ impl ComponentTypesBuilder { self.add_enum_type(TypeEnum { names, abi, info }) } - fn union_type( - &mut self, - types: types::TypesRef<'_>, - ty: &types::UnionType, - ) -> Result { - let types = ty - .types - .iter() - .map(|ty| self.valtype(types, ty)) - .collect::>>()?; - let (info, abi) = VariantInfo::new( - types - .iter() - .map(|t| Some(self.component_types.canonical_abi(t))), - ); - Ok(self.add_union_type(TypeUnion { types, abi, info })) - } - fn option_type( &mut self, types: types::TypesRef<'_>, @@ -828,11 +801,6 @@ impl ComponentTypesBuilder { intern_and_fill_flat_types!(self, variants, ty) } - /// Interns a new union type within this type information. - pub fn add_union_type(&mut self, ty: TypeUnion) -> TypeUnionIndex { - intern_and_fill_flat_types!(self, unions, ty) - } - /// Interns a new enum type within this type information. pub fn add_enum_type(&mut self, ty: TypeEnum) -> TypeEnumIndex { intern_and_fill_flat_types!(self, enums, ty) @@ -918,7 +886,6 @@ impl ComponentTypesBuilder { InterfaceType::Tuple(i) => &self.type_info.tuples[*i], InterfaceType::Flags(i) => &self.type_info.flags[*i], InterfaceType::Enum(i) => &self.type_info.enums[*i], - InterfaceType::Union(i) => &self.type_info.unions[*i], InterfaceType::Option(i) => &self.type_info.options[*i], InterfaceType::Result(i) => &self.type_info.results[*i], } @@ -1065,7 +1032,6 @@ pub enum InterfaceType { Tuple(TypeTupleIndex), Flags(TypeFlagsIndex), Enum(TypeEnumIndex), - Union(TypeUnionIndex), Option(TypeOptionIndex), Result(TypeResultIndex), Own(TypeResourceTableIndex), @@ -1511,21 +1477,6 @@ pub struct TypeEnum { pub info: VariantInfo, } -/// Shape of a "union" type in interface types. -/// -/// Note that this can be viewed as a specialization of the `variant` interface -/// type where each type here has a name that's numbered. This is still a -/// tagged union. -#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)] -pub struct TypeUnion { - /// The list of types this is a union over. - pub types: Box<[InterfaceType]>, - /// Byte information about this type in the canonical ABI. - pub abi: CanonicalAbiInfo, - /// Byte information about this variant type. - pub info: VariantInfo, -} - /// Shape of an "option" interface type. #[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)] pub struct TypeOption { @@ -1715,7 +1666,6 @@ struct TypeInformationCache { tuples: PrimaryMap, enums: PrimaryMap, flags: PrimaryMap, - unions: PrimaryMap, options: PrimaryMap, results: PrimaryMap, lists: PrimaryMap, @@ -1896,10 +1846,6 @@ impl TypeInformation { ) } - fn unions(&mut self, types: &ComponentTypesBuilder, ty: &TypeUnion) { - self.build_variant(ty.types.iter().map(|t| Some(types.type_information(t)))) - } - fn results(&mut self, types: &ComponentTypesBuilder, ty: &TypeResult) { self.build_variant([ ty.ok.as_ref().map(|ty| types.type_information(ty)), diff --git a/crates/environ/src/fact/trampoline.rs b/crates/environ/src/fact/trampoline.rs index 000d843e2ef8..5936de013d39 100644 --- a/crates/environ/src/fact/trampoline.rs +++ b/crates/environ/src/fact/trampoline.rs @@ -18,8 +18,8 @@ use crate::component::{ CanonicalAbiInfo, ComponentTypesBuilder, FlatType, InterfaceType, StringEncoding, TypeEnumIndex, TypeFlagsIndex, TypeListIndex, TypeOptionIndex, TypeRecordIndex, - TypeResourceTableIndex, TypeResultIndex, TypeTupleIndex, TypeUnionIndex, TypeVariantIndex, - VariantInfo, FLAG_MAY_ENTER, FLAG_MAY_LEAVE, MAX_FLAT_PARAMS, MAX_FLAT_RESULTS, + TypeResourceTableIndex, TypeResultIndex, TypeTupleIndex, TypeVariantIndex, VariantInfo, + FLAG_MAY_ENTER, FLAG_MAY_LEAVE, MAX_FLAT_PARAMS, MAX_FLAT_RESULTS, }; use crate::fact::signature::Signature; use crate::fact::transcode::{FixedEncoding as FE, Transcode, Transcoder}; @@ -580,7 +580,6 @@ impl Compiler<'_, '_> { InterfaceType::Record(i) => self.types[*i].fields.len(), InterfaceType::Tuple(i) => self.types[*i].types.len(), InterfaceType::Variant(i) => self.types[*i].cases.len(), - InterfaceType::Union(i) => self.types[*i].types.len(), InterfaceType::Enum(i) => self.types[*i].names.len(), // 2 cases to consider for each of these variants. @@ -617,7 +616,6 @@ impl Compiler<'_, '_> { InterfaceType::Flags(f) => self.translate_flags(*f, src, dst_ty, dst), InterfaceType::Tuple(t) => self.translate_tuple(*t, src, dst_ty, dst), InterfaceType::Variant(v) => self.translate_variant(*v, src, dst_ty, dst), - InterfaceType::Union(u) => self.translate_union(*u, src, dst_ty, dst), InterfaceType::Enum(t) => self.translate_enum(*t, src, dst_ty, dst), InterfaceType::Option(t) => self.translate_option(*t, src, dst_ty, dst), InterfaceType::Result(t) => self.translate_result(*t, src, dst_ty, dst), @@ -2203,44 +2201,6 @@ impl Compiler<'_, '_> { self.convert_variant(src, &src_info, dst, &dst_info, iter); } - fn translate_union( - &mut self, - src_ty: TypeUnionIndex, - src: &Source<'_>, - dst_ty: &InterfaceType, - dst: &Destination, - ) { - let src_ty = &self.types[src_ty]; - let dst_ty = match dst_ty { - InterfaceType::Union(t) => &self.types[*t], - _ => panic!("expected an option"), - }; - assert_eq!(src_ty.types.len(), dst_ty.types.len()); - let src_info = variant_info(self.types, src_ty.types.iter().map(Some)); - let dst_info = variant_info(self.types, dst_ty.types.iter().map(Some)); - - self.convert_variant( - src, - &src_info, - dst, - &dst_info, - src_ty - .types - .iter() - .zip(dst_ty.types.iter()) - .enumerate() - .map(|(i, (src_ty, dst_ty))| { - let i = u32::try_from(i).unwrap(); - VariantCase { - src_i: i, - dst_i: i, - src_ty: Some(src_ty), - dst_ty: Some(dst_ty), - } - }), - ); - } - fn translate_enum( &mut self, src_ty: TypeEnumIndex, diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs index df914055491c..00a5885c6f7e 100644 --- a/crates/environ/src/module_environ.rs +++ b/crates/environ/src/module_environ.rs @@ -16,8 +16,8 @@ use std::path::PathBuf; use std::sync::Arc; use wasmparser::{ types::Types, CustomSectionReader, DataKind, ElementItems, ElementKind, Encoding, ExternalKind, - FuncToValidate, FunctionBody, NameSectionReader, Naming, Operator, Parser, Payload, - StructuralType, TypeRef, Validator, ValidatorResources, + FuncToValidate, FunctionBody, NameSectionReader, Naming, Operator, Parser, Payload, TypeRef, + Validator, ValidatorResources, }; /// Object containing the standalone environment information. @@ -237,24 +237,9 @@ impl<'a, 'data> ModuleEnvironment<'a, 'data> { self.result.module.types.reserve(num); self.types.reserve_wasm_signatures(num); - for ty in types { - let ty = ty?; - if ty.types().len() != 1 { - unimplemented!("gc proposal") - } - let ty = ty.types().first().unwrap(); - if ty.is_final || ty.supertype_idx.is_some() { - unimplemented!("gc proposal") - } - match &ty.structural_type { - StructuralType::Func(wasm_func_ty) => { - let ty = self.convert_func_type(&wasm_func_ty); - self.declare_type_func(ty)?; - } - StructuralType::Array(_) | StructuralType::Struct(_) => { - unimplemented!("gc proposal") - } - } + for ty in types.into_iter_err_on_gc_types() { + let ty = self.convert_func_type(&ty?); + self.declare_type_func(ty)?; } } diff --git a/crates/fuzzing/src/generators/component_types.rs b/crates/fuzzing/src/generators/component_types.rs index 36ea589a5b01..80b2838b1576 100644 --- a/crates/fuzzing/src/generators/component_types.rs +++ b/crates/fuzzing/src/generators/component_types.rs @@ -78,15 +78,6 @@ pub fn arbitrary_val(ty: &component::Type, input: &mut Unstructured) -> arbitrar let name = input.choose(&names)?; en.new_val(name).unwrap() } - Type::Union(un) => { - let mut types = un.types(); - let discriminant = input.int_in_range(0..=types.len() - 1)?; - un.new_val( - discriminant.try_into().unwrap(), - arbitrary_val(&types.nth(discriminant).unwrap(), input)?, - ) - .unwrap() - } Type::Option(option) => { let discriminant = input.int_in_range(0..=1)?; option diff --git a/crates/misc/component-fuzz-util/src/lib.rs b/crates/misc/component-fuzz-util/src/lib.rs index 8d5c6458a04f..477681b6bf49 100644 --- a/crates/misc/component-fuzz-util/src/lib.rs +++ b/crates/misc/component-fuzz-util/src/lib.rs @@ -126,7 +126,6 @@ pub enum Type { // least one case. Variant(VecInRange, 1, 200>), Enum(u32), - Union(VecInRange), Option(Box), Result { @@ -144,7 +143,7 @@ impl Type { fuel: &mut u32, ) -> arbitrary::Result { *fuel = fuel.saturating_sub(1); - let max = if depth == 0 || *fuel == 0 { 12 } else { 21 }; + let max = if depth == 0 || *fuel == 0 { 12 } else { 20 }; Ok(match u.int_in_range(0..=max)? { 0 => Type::Bool, 1 => Type::S8, @@ -171,13 +170,12 @@ impl Type { *fuel -= amt; Type::Enum(amt) } - 18 => Type::Union(Type::generate_list(u, depth - 1, fuel)?), - 19 => Type::Option(Box::new(Type::generate(u, depth - 1, fuel)?)), - 20 => Type::Result { + 18 => Type::Option(Box::new(Type::generate(u, depth - 1, fuel)?)), + 19 => Type::Result { ok: Type::generate_opt(u, depth - 1, fuel)?.map(Box::new), err: Type::generate_opt(u, depth - 1, fuel)?.map(Box::new), }, - 21 => { + 20 => { // Generate 1 flag all the way up to 65 flags which exercises // the 1 to 3 x u32 cases. let amt = u.int_in_range(1..=(*fuel).min(65))?; @@ -276,7 +274,6 @@ impl Type { Type::Record(types) => lower_record(types.iter(), vec), Type::Tuple(types) => lower_record(types.0.iter(), vec), Type::Variant(types) => lower_variant(types.0.iter().map(|t| t.as_ref()), vec), - Type::Union(types) => lower_variant(types.0.iter().map(Some), vec), Type::Option(ty) => lower_variant([None, Some(&**ty)].into_iter(), vec), Type::Result { ok, err } => { lower_variant([ok.as_deref(), err.as_deref()].into_iter(), vec) @@ -319,7 +316,6 @@ impl Type { Type::Tuple(types) => record_size_and_alignment(types.0.iter()), Type::Variant(types) => variant_size_and_alignment(types.0.iter().map(|t| t.as_ref())), - Type::Union(types) => variant_size_and_alignment(types.0.iter().map(Some)), Type::Enum(count) => variant_size_and_alignment((0..*count).map(|_| None)), @@ -566,29 +562,6 @@ pub fn rust_type(ty: &Type, name_counter: &mut u32, declarations: &mut TokenStre quote!(#name) } - Type::Union(types) => { - let cases = types - .0 - .iter() - .enumerate() - .map(|(index, ty)| { - let name = format_ident!("U{index}"); - let ty = rust_type(ty, name_counter, declarations); - quote!(#name(#ty),) - }) - .collect::(); - let name = make_rust_name(name_counter); - - declarations.extend(quote! { - #[derive(ComponentType, Lift, Lower, PartialEq, Debug, Clone, Arbitrary)] - #[component(union)] - enum #name { - #cases - } - }); - - quote!(#name) - } Type::Enum(count) => { let cases = (0..*count) .map(|index| { @@ -692,7 +665,6 @@ impl<'a> TypesBuilder<'a> { | Type::Tuple(_) | Type::Variant(_) | Type::Enum(_) - | Type::Union(_) | Type::Option(_) | Type::Result { .. } | Type::Flags(_) => { @@ -762,14 +734,6 @@ impl<'a> TypesBuilder<'a> { } decl.push_str(")"); } - Type::Union(types) => { - decl.push_str("(union"); - for ty in types.iter() { - decl.push_str(" "); - self.write_ref(ty, &mut decl); - } - decl.push_str(")"); - } Type::Option(ty) => { decl.push_str("(option "); self.write_ref(ty, &mut decl); diff --git a/crates/wasmtime/src/component/func/typed.rs b/crates/wasmtime/src/component/func/typed.rs index 1295994daad7..93b74c138934 100644 --- a/crates/wasmtime/src/component/func/typed.rs +++ b/crates/wasmtime/src/component/func/typed.rs @@ -1659,34 +1659,6 @@ pub fn typecheck_enum( } } -/// Verify that the given wasm type is a union with the expected cases in the right order. -pub fn typecheck_union( - ty: &InterfaceType, - types: &InstanceType<'_>, - expected: &[fn(&InterfaceType, &InstanceType<'_>) -> Result<()>], -) -> Result<()> { - match ty { - InterfaceType::Union(index) => { - let union_types = &types.types[*index].types; - - if union_types.len() != expected.len() { - bail!( - "expected union of {} types, found {} types", - expected.len(), - union_types.len() - ); - } - - for (index, (ty, check)) in union_types.iter().zip(expected).enumerate() { - check(ty, types).with_context(|| format!("type mismatch for case {}", index))?; - } - - Ok(()) - } - other => bail!("expected `union` found `{}`", desc(other)), - } -} - /// Verify that the given wasm type is a flags type with the expected flags in the right order and with the right /// names. pub fn typecheck_flags( @@ -2310,7 +2282,6 @@ pub fn desc(ty: &InterfaceType) -> &'static str { InterfaceType::Variant(_) => "variant", InterfaceType::Flags(_) => "flags", InterfaceType::Enum(_) => "enum", - InterfaceType::Union(_) => "union", InterfaceType::Own(_) => "owned resource", InterfaceType::Borrow(_) => "borrowed resource", } diff --git a/crates/wasmtime/src/component/mod.rs b/crates/wasmtime/src/component/mod.rs index a486ebe68850..4129975def45 100644 --- a/crates/wasmtime/src/component/mod.rs +++ b/crates/wasmtime/src/component/mod.rs @@ -23,9 +23,7 @@ pub use self::instance::{ExportInstance, Exports, Instance, InstancePre}; pub use self::linker::{Linker, LinkerInstance}; pub use self::resources::{Resource, ResourceAny}; pub use self::types::{ResourceType, Type}; -pub use self::values::{ - Enum, Flags, List, OptionVal, Record, ResultVal, Tuple, Union, Val, Variant, -}; +pub use self::values::{Enum, Flags, List, OptionVal, Record, ResultVal, Tuple, Val, Variant}; pub use wasmtime_component_macro::{flags, ComponentType, Lift, Lower}; // These items are expected to be used by an eventual @@ -35,8 +33,8 @@ pub use wasmtime_component_macro::{flags, ComponentType, Lift, Lower}; pub mod __internal { pub use super::func::{ bad_type_info, format_flags, lower_payload, typecheck_enum, typecheck_flags, - typecheck_record, typecheck_union, typecheck_variant, ComponentVariant, LiftContext, - LowerContext, MaybeUninitExt, Options, + typecheck_record, typecheck_variant, ComponentVariant, LiftContext, LowerContext, + MaybeUninitExt, Options, }; pub use super::matching::InstanceType; pub use crate::map_maybe_uninit; diff --git a/crates/wasmtime/src/component/types.rs b/crates/wasmtime/src/component/types.rs index 23d08ba1b600..43b25a13c388 100644 --- a/crates/wasmtime/src/component/types.rs +++ b/crates/wasmtime/src/component/types.rs @@ -10,7 +10,7 @@ use std::sync::Arc; use wasmtime_environ::component::{ CanonicalAbiInfo, ComponentTypes, InterfaceType, ResourceIndex, TypeEnumIndex, TypeFlagsIndex, TypeListIndex, TypeOptionIndex, TypeRecordIndex, TypeResultIndex, TypeTupleIndex, - TypeUnionIndex, TypeVariantIndex, + TypeVariantIndex, }; use wasmtime_environ::PrimaryMap; @@ -210,29 +210,6 @@ impl Enum { } } -/// A `union` interface type -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct Union(Handle); - -impl Union { - /// Instantiate this type with the specified `discriminant` and `value`. - pub fn new_val(&self, discriminant: u32, value: Val) -> Result { - Ok(Val::Union(values::Union::new(self, discriminant, value)?)) - } - - pub(crate) fn from(index: TypeUnionIndex, ty: &InstanceType<'_>) -> Self { - Union(Handle::new(index, ty)) - } - - /// Retrieve the types of the cases of this `union` in declaration order. - pub fn types(&self) -> impl ExactSizeIterator + '_ { - self.0.types[self.0.index] - .types - .iter() - .map(|ty| Type::from(ty, &self.0.instance())) - } -} - /// An `option` interface type #[derive(Clone, PartialEq, Eq, Debug)] pub struct OptionType(Handle); @@ -333,7 +310,6 @@ pub enum Type { Tuple(Tuple), Variant(Variant), Enum(Enum), - Union(Union), Option(OptionType), Result(ResultType), Flags(Flags), @@ -407,19 +383,6 @@ impl Type { } } - /// Retrieve the inner [`Union`] of a [`Type::Union`]. - /// - /// # Panics - /// - /// This will panic if `self` is not a [`Type::Union`]. - pub fn unwrap_union(&self) -> &Union { - if let Type::Union(handle) = self { - &handle - } else { - panic!("attempted to unwrap a {} as a union", self.desc()) - } - } - /// Retrieve the inner [`OptionType`] of a [`Type::Option`]. /// /// # Panics @@ -522,7 +485,6 @@ impl Type { InterfaceType::Tuple(index) => Type::Tuple(Tuple::from(*index, instance)), InterfaceType::Variant(index) => Type::Variant(Variant::from(*index, instance)), InterfaceType::Enum(index) => Type::Enum(Enum::from(*index, instance)), - InterfaceType::Union(index) => Type::Union(Union::from(*index, instance)), InterfaceType::Option(index) => Type::Option(OptionType::from(*index, instance)), InterfaceType::Result(index) => Type::Result(ResultType::from(*index, instance)), InterfaceType::Flags(index) => Type::Flags(Flags::from(*index, instance)), @@ -551,7 +513,6 @@ impl Type { Type::Tuple(_) => "tuple", Type::Variant(_) => "variant", Type::Enum(_) => "enum", - Type::Union(_) => "union", Type::Option(_) => "option", Type::Result(_) => "result", Type::Flags(_) => "flags", diff --git a/crates/wasmtime/src/component/values.rs b/crates/wasmtime/src/component/values.rs index f40a8f473947..332a0659a875 100644 --- a/crates/wasmtime/src/component/values.rs +++ b/crates/wasmtime/src/component/values.rs @@ -328,79 +328,6 @@ impl fmt::Debug for Enum { } } -/// Represents runtime union values -#[derive(PartialEq, Eq, Clone)] -pub struct Union { - ty: types::Union, - discriminant: u32, - value: Option>, -} - -impl Union { - /// Instantiate the specified type with the specified `discriminant` and `value`. - pub fn new(ty: &types::Union, discriminant: u32, value: Val) -> Result { - if let Some(case_ty) = ty.types().nth(usize::try_from(discriminant)?) { - case_ty - .check(&value) - .with_context(|| format!("type mismatch for case {discriminant} of union"))?; - - Ok(Self { - ty: ty.clone(), - discriminant, - value: Some(Box::new(value)), - }) - } else { - Err(anyhow!( - "discriminant {discriminant} out of range: [0,{})", - ty.types().len() - )) - } - } - - /// Returns the type of this value. - pub fn ty(&self) -> &types::Union { - &self.ty - } - - /// Returns name of the discriminant of this value within the union type. - pub fn discriminant(&self) -> u32 { - self.discriminant - } - - /// Returns the payload value for this union. - pub fn payload(&self) -> &Val { - self.value.as_ref().unwrap() - } - - fn as_generic<'a>( - &'a self, - types: &'a ComponentTypes, - ty: InterfaceType, - ) -> GenericVariant<'a> { - let ty = match ty { - InterfaceType::Union(i) => &types[i], - _ => bad_type_info(), - }; - GenericVariant { - discriminant: self.discriminant, - abi: &ty.abi, - info: &ty.info, - payload: self - .value - .as_deref() - .zip(Some(ty.types[self.discriminant as usize])), - } - } -} - -impl fmt::Debug for Union { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple(&format!("U{}", self.discriminant())) - .field(self.payload()) - .finish() - } -} - /// Represents runtime option values #[derive(PartialEq, Eq, Clone)] pub struct OptionVal { @@ -652,7 +579,6 @@ pub enum Val { Tuple(Tuple), Variant(Variant), Enum(Enum), - Union(Union), Option(OptionVal), Result(ResultVal), Flags(Flags), @@ -681,7 +607,6 @@ impl Val { Val::Tuple(Tuple { ty, .. }) => Type::Tuple(ty.clone()), Val::Variant(Variant { ty, .. }) => Type::Variant(ty.clone()), Val::Enum(Enum { ty, .. }) => Type::Enum(ty.clone()), - Val::Union(Union { ty, .. }) => Type::Union(ty.clone()), Val::Option(OptionVal { ty, .. }) => Type::Option(ty.clone()), Val::Result(ResultVal { ty, .. }) => Type::Result(ty.clone()), Val::Flags(Flags { ty, .. }) => Type::Flags(ty.clone()), @@ -769,20 +694,6 @@ impl Val { discriminant, }) } - InterfaceType::Union(i) => { - let (discriminant, value) = lift_variant( - cx, - cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(), - cx.types[i].types.iter().copied().map(Some), - src, - )?; - - Val::Union(Union { - ty: types::Union::from(i, &cx.instance_type()), - discriminant, - value, - }) - } InterfaceType::Option(i) => { let (discriminant, value) = lift_variant( cx, @@ -883,17 +794,6 @@ impl Val { discriminant, }) } - InterfaceType::Union(i) => { - let ty = &cx.types[i]; - let (discriminant, value) = - load_variant(cx, &ty.info, ty.types.iter().copied().map(Some), bytes)?; - - Val::Union(Union { - ty: types::Union::from(i, &cx.instance_type()), - discriminant, - value, - }) - } InterfaceType::Option(i) => { let ty = &cx.types[i]; let (discriminant, value) = @@ -997,7 +897,6 @@ impl Val { } } Val::Variant(v) => v.as_generic(cx.types, ty).lower(cx, dst)?, - Val::Union(v) => v.as_generic(cx.types, ty).lower(cx, dst)?, Val::Option(v) => v.as_generic(cx.types, ty).lower(cx, dst)?, Val::Result(v) => v.as_generic(cx.types, ty).lower(cx, dst)?, Val::Enum(Enum { discriminant, .. }) => { @@ -1080,7 +979,6 @@ impl Val { Val::Variant(v) => v.as_generic(cx.types, ty).store(cx, offset)?, Val::Enum(v) => v.as_generic(cx.types, ty).store(cx, offset)?, - Val::Union(v) => v.as_generic(cx.types, ty).store(cx, offset)?, Val::Option(v) => v.as_generic(cx.types, ty).store(cx, offset)?, Val::Result(v) => v.as_generic(cx.types, ty).store(cx, offset)?, @@ -1165,8 +1063,6 @@ impl PartialEq for Val { (Self::Variant(_), _) => false, (Self::Enum(l), Self::Enum(r)) => l == r, (Self::Enum(_), _) => false, - (Self::Union(l), Self::Union(r)) => l == r, - (Self::Union(_), _) => false, (Self::Option(l), Self::Option(r)) => l == r, (Self::Option(_), _) => false, (Self::Result(l), Self::Result(r)) => l == r, diff --git a/crates/wast/src/component.rs b/crates/wast/src/component.rs index 4975009821d7..2ce11c8651d1 100644 --- a/crates/wast/src/component.rs +++ b/crates/wast/src/component.rs @@ -87,17 +87,6 @@ pub fn val(v: &WastVal<'_>, ty: &Type) -> Result { } _ => bail!("expected a variant value"), }, - WastVal::Union(idx, payload) => match ty { - Type::Union(t) => { - let case = match t.types().nth(*idx as usize) { - Some(case) => case, - None => bail!("case {idx} too large"), - }; - let payload = val(payload, &case)?; - t.new_val(*idx, payload)? - } - _ => bail!("expected a union value"), - }, WastVal::Option(v) => match ty { Type::Option(t) => { let v = match v { @@ -260,15 +249,6 @@ pub fn match_val(expected: &WastVal<'_>, actual: &Val) -> Result<()> { } _ => mismatch(expected, actual), }, - WastVal::Union(idx, e) => match actual { - Val::Union(a) => { - if a.discriminant() != *idx { - bail!("expected discriminant `{idx}` got `{}`", a.discriminant()); - } - match_val(e, a.payload()) - } - _ => mismatch(expected, actual), - }, WastVal::Option(e) => match actual { Val::Option(a) => match (e, a.value()) { (None, None) => Ok(()), @@ -348,7 +328,6 @@ fn mismatch(expected: &WastVal<'_>, actual: &Val) -> Result<()> { WastVal::Tuple(..) => "tuple", WastVal::Enum(..) => "enum", WastVal::Variant(..) => "variant", - WastVal::Union(..) => "union", WastVal::Option(..) => "option", WastVal::Result(..) => "result", WastVal::Flags(..) => "flags", @@ -372,7 +351,6 @@ fn mismatch(expected: &WastVal<'_>, actual: &Val) -> Result<()> { Val::Tuple(..) => "tuple", Val::Enum(..) => "enum", Val::Variant(..) => "variant", - Val::Union(..) => "union", Val::Option(..) => "option", Val::Result(..) => "result", Val::Flags(..) => "flags", diff --git a/crates/wit-bindgen/src/lib.rs b/crates/wit-bindgen/src/lib.rs index 2d86124f1a8d..09a47e212f1e 100644 --- a/crates/wit-bindgen/src/lib.rs +++ b/crates/wit-bindgen/src/lib.rs @@ -765,7 +765,6 @@ impl<'a> InterfaceGenerator<'a> { TypeDefKind::Variant(variant) => self.type_variant(id, name, variant, &ty.docs), TypeDefKind::Option(t) => self.type_option(id, name, t, &ty.docs), TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs), - TypeDefKind::Union(u) => self.type_union(id, name, u, &ty.docs), TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs), TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs), TypeDefKind::Future(_) => todo!("generate for future"), @@ -902,16 +901,6 @@ impl<'a> InterfaceGenerator<'a> { ); } - fn type_union(&mut self, id: TypeId, _name: &str, union: &Union, docs: &Docs) { - self.print_rust_enum( - id, - std::iter::zip(self.union_case_names(union), &union.cases) - .map(|(name, case)| (name, None, &case.docs, Some(&case.ty))), - docs, - "union", - ); - } - fn type_option(&mut self, id: TypeId, _name: &str, payload: &Type, docs: &Docs) { let info = self.info(id); diff --git a/crates/wit-bindgen/src/rust.rs b/crates/wit-bindgen/src/rust.rs index ec9f729c5835..48100dfaf36c 100644 --- a/crates/wit-bindgen/src/rust.rs +++ b/crates/wit-bindgen/src/rust.rs @@ -1,7 +1,5 @@ use crate::{types::TypeInfo, Ownership}; use heck::*; -use std::collections::HashMap; -use std::fmt::Write; use wit_parser::*; #[derive(Debug, Copy, Clone, PartialEq)] @@ -117,7 +115,6 @@ pub trait RustGenerator<'a> { | TypeDefKind::Flags(_) | TypeDefKind::Enum(_) | TypeDefKind::Tuple(_) - | TypeDefKind::Union(_) | TypeDefKind::Handle(_) | TypeDefKind::Resource => true, TypeDefKind::Type(Type::Id(t)) => { @@ -169,9 +166,6 @@ pub trait RustGenerator<'a> { TypeDefKind::Enum(_) => { panic!("unsupported anonymous type reference: enum") } - TypeDefKind::Union(_) => { - panic!("unsupported anonymous type reference: union") - } TypeDefKind::Future(ty) => { self.push_str("Future<"); self.print_optional_ty(ty.as_ref(), mode); @@ -250,119 +244,6 @@ pub trait RustGenerator<'a> { result } - /// Writes the camel-cased 'name' of the passed type to `out`, as used to name union variants. - fn write_name(&self, ty: &Type, out: &mut String) { - match ty { - Type::Bool => out.push_str("Bool"), - Type::U8 => out.push_str("U8"), - Type::U16 => out.push_str("U16"), - Type::U32 => out.push_str("U32"), - Type::U64 => out.push_str("U64"), - Type::S8 => out.push_str("I8"), - Type::S16 => out.push_str("I16"), - Type::S32 => out.push_str("I32"), - Type::S64 => out.push_str("I64"), - Type::Float32 => out.push_str("F32"), - Type::Float64 => out.push_str("F64"), - Type::Char => out.push_str("Char"), - Type::String => out.push_str("String"), - Type::Id(id) => { - let ty = &self.resolve().types[*id]; - match &ty.name { - Some(name) => out.push_str(&name.to_upper_camel_case()), - None => match &ty.kind { - TypeDefKind::Option(ty) => { - out.push_str("Optional"); - self.write_name(ty, out); - } - TypeDefKind::Result(_) => out.push_str("Result"), - TypeDefKind::Tuple(_) => out.push_str("Tuple"), - TypeDefKind::List(ty) => { - self.write_name(ty, out); - out.push_str("List") - } - TypeDefKind::Future(ty) => { - self.write_optional_name(ty.as_ref(), out); - out.push_str("Future"); - } - TypeDefKind::Stream(s) => { - self.write_optional_name(s.element.as_ref(), out); - self.write_optional_name(s.end.as_ref(), out); - out.push_str("Stream"); - } - - TypeDefKind::Type(ty) => self.write_name(ty, out), - TypeDefKind::Record(_) => out.push_str("Record"), - TypeDefKind::Flags(_) => out.push_str("Flags"), - TypeDefKind::Variant(_) => out.push_str("Variant"), - TypeDefKind::Enum(_) => out.push_str("Enum"), - TypeDefKind::Union(_) => out.push_str("Union"), - TypeDefKind::Handle(_) => todo!("#6722"), - TypeDefKind::Resource => todo!("#6722"), - TypeDefKind::Unknown => unreachable!(), - }, - } - } - } - } - - fn write_optional_name(&self, ty: Option<&Type>, out: &mut String) { - match ty { - Some(ty) => self.write_name(ty, out), - None => out.push_str("()"), - } - } - - /// Returns the names for the cases of the passed union. - fn union_case_names(&self, union: &Union) -> Vec { - enum UsedState<'a> { - /// This name has been used once before. - /// - /// Contains a reference to the name given to the first usage so that a suffix can be added to it. - Once(&'a mut String), - /// This name has already been used multiple times. - /// - /// Contains the number of times this has already been used. - Multiple(usize), - } - - // A `Vec` of the names we're assigning each of the union's cases in order. - let mut case_names = vec![String::new(); union.cases.len()]; - // A map from case names to their `UsedState`. - let mut used = HashMap::new(); - for (case, name) in union.cases.iter().zip(case_names.iter_mut()) { - self.write_name(&case.ty, name); - - match used.get_mut(name.as_str()) { - None => { - // Initialise this name's `UsedState`, with a mutable reference to this name - // in case we have to add a suffix to it later. - used.insert(name.clone(), UsedState::Once(name)); - // Since this is the first (and potentially only) usage of this name, - // we don't need to add a suffix here. - } - Some(state) => match state { - UsedState::Multiple(n) => { - // Add a suffix of the index of this usage. - write!(name, "{n}").unwrap(); - // Add one to the number of times this type has been used. - *n += 1; - } - UsedState::Once(first) => { - // Add a suffix of 0 to the first usage. - first.push('0'); - // We now get a suffix of 1. - name.push('1'); - // Then update the state. - *state = UsedState::Multiple(2); - } - }, - } - } - - case_names - } - fn param_name(&self, ty: TypeId) -> String { let info = self.info(ty); let name = self.resolve().types[ty] diff --git a/crates/wit-bindgen/src/types.rs b/crates/wit-bindgen/src/types.rs index 9f8d9e89c90f..ad9d25b67a35 100644 --- a/crates/wit-bindgen/src/types.rs +++ b/crates/wit-bindgen/src/types.rs @@ -146,11 +146,6 @@ impl Types { info = self.optional_type_info(resolve, r.ok.as_ref()); info |= self.optional_type_info(resolve, r.err.as_ref()); } - TypeDefKind::Union(u) => { - for case in u.cases.iter() { - info |= self.type_info(resolve, &case.ty); - } - } TypeDefKind::Future(ty) => { info = self.optional_type_info(resolve, ty.as_ref()); } diff --git a/tests/all/component_model/dynamic.rs b/tests/all/component_model/dynamic.rs index 4f409262871f..6d24163c58f0 100644 --- a/tests/all/component_model/dynamic.rs +++ b/tests/all/component_model/dynamic.rs @@ -436,8 +436,6 @@ fn everything() -> Result<()> { (case "M" $m) )) (export $j "j" (type $j')) - (type $z' (union u32 float64)) - (export $z "z" (type $z')) (type $Foo' (record (field "A" u32) @@ -454,7 +452,6 @@ fn everything() -> Result<()> { (field "V" string) (field "W" char) (field "Y" (tuple u32 u32)) - (field "Z" $z) (field "AA" (option u32)) (field "BB" (result string (error string))) )) @@ -497,8 +494,8 @@ fn everything() -> Result<()> { .fields() .map(|field| field.ty) .collect::>(); - let (b_type, c_type, f_type, j_type, y_type, z_type, aa_type, bb_type) = ( - &types[1], &types[2], &types[3], &types[4], &types[13], &types[14], &types[15], &types[16], + let (b_type, c_type, f_type, j_type, y_type, aa_type, bb_type) = ( + &types[1], &types[2], &types[3], &types[4], &types[13], &types[14], &types[15], ); let f_element_type = &f_type.unwrap_list().ty(); let input = ty.unwrap_record().new_val([ @@ -536,10 +533,6 @@ fn everything() -> Result<()> { .unwrap_tuple() .new_val(Box::new([Val::U32(42), Val::U32(24)]))?, ), - ( - "Z", - z_type.unwrap_union().new_val(1, Val::Float64(3.14159265))?, - ), ( "AA", aa_type.unwrap_option().new_val(Some(Val::U32(314159265)))?, diff --git a/tests/all/component_model/macros.rs b/tests/all/component_model/macros.rs index 0bd2b2b5c83d..cf59adb484c9 100644 --- a/tests/all/component_model/macros.rs +++ b/tests/all/component_model/macros.rs @@ -115,94 +115,6 @@ fn record_derive() -> Result<()> { Ok(()) } -#[test] -fn union_derive() -> Result<()> { - #[derive(ComponentType, Lift, Lower, PartialEq, Debug, Copy, Clone)] - #[component(union)] - enum Foo { - A(i32), - B(u32), - C(i32), - } - - let engine = super::engine(); - let mut store = Store::new(&engine, ()); - - // Happy path: component type matches case count and types - - let component = Component::new(&engine, make_echo_component("(union s32 u32 s32)", 8))?; - let instance = Linker::new(&engine).instantiate(&mut store, &component)?; - let func = instance.get_typed_func::<(Foo,), (Foo,)>(&mut store, "echo")?; - - for &input in &[Foo::A(-42), Foo::B(73), Foo::C(314159265)] { - let output = func.call_and_post_return(&mut store, (input,))?; - - assert_eq!((input,), output); - } - - // Sad path: case count mismatch (too few) - - let component = Component::new(&engine, make_echo_component("(union s32 u32)", 8))?; - let instance = Linker::new(&engine).instantiate(&mut store, &component)?; - - assert!(instance - .get_typed_func::<(Foo,), (Foo,)>(&mut store, "echo") - .is_err()); - - // Sad path: case count mismatch (too many) - - let component = Component::new( - &engine, - make_echo_component(r#"(union s32 u32 s32 s32)"#, 8), - )?; - let instance = Linker::new(&engine).instantiate(&mut store, &component)?; - - assert!(instance - .get_typed_func::<(Foo,), (Foo,)>(&mut store, "echo") - .is_err()); - - assert!(instance - .get_typed_func::<(Foo,), (Foo,)>(&mut store, "echo") - .is_err()); - - // Sad path: case type mismatch - - let component = Component::new(&engine, make_echo_component("(union s32 s32 s32)", 8))?; - let instance = Linker::new(&engine).instantiate(&mut store, &component)?; - - assert!(instance - .get_typed_func::<(Foo,), (Foo,)>(&mut store, "echo") - .is_err()); - - // Happy path redux, with generics this time - - #[derive(ComponentType, Lift, Lower, PartialEq, Debug, Copy, Clone)] - #[component(union)] - enum Generic { - A(A), - B(B), - C(C), - } - - let component = Component::new(&engine, make_echo_component("(union s32 u32 s32)", 8))?; - let instance = Linker::new(&engine).instantiate(&mut store, &component)?; - let func = instance.get_typed_func::<(Generic,), (Generic,)>( - &mut store, "echo", - )?; - - for &input in &[ - Generic::::A(-42), - Generic::B(73), - Generic::C(314159265), - ] { - let output = func.call_and_post_return(&mut store, (input,))?; - - assert_eq!((input,), output); - } - - Ok(()) -} - #[test] fn variant_derive() -> Result<()> { #[derive(ComponentType, Lift, Lower, PartialEq, Eq, Debug, Copy, Clone)] diff --git a/tests/misc_testsuite/component-model/types.wast b/tests/misc_testsuite/component-model/types.wast index ebe154ca9d44..79df86454756 100644 --- a/tests/misc_testsuite/component-model/types.wast +++ b/tests/misc_testsuite/component-model/types.wast @@ -2,7 +2,7 @@ (type string) (type (func (param "a" string))) (type $r (record (field "x" (result)) (field "y" string))) - (type $u (union $r string)) + (type $u (variant (case "r" $r) (case "s" string))) (type $e (result $u (error u32))) (type (result $u)) (type (result (error $u)))