From f96491f3337a8ccb792b2769b016de6c16022ede Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 12 Oct 2022 15:45:03 -0700 Subject: [PATCH] Ignore when components export type definitions (#5051) * allow a ComponentTypeRef::Type to point to a component TypeDef * component matching: don't assert exported Interface type definitions are "defined" types may be exported by their name for consumption by some component runtimes, but in wasmtime this doesn't matter (we lift and lower to types, not define them) so we should ignore these. * component-model instance tests: show that an import can export a type definition this is meaningless, but it should be accepted. (previously rejected) --- crates/environ/src/component/types.rs | 4 +--- crates/wasmtime/src/component/matching.rs | 6 ++++++ tests/misc_testsuite/component-model/instance.wast | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/environ/src/component/types.rs b/crates/environ/src/component/types.rs index b6666308d4..4c715b61ef 100644 --- a/crates/environ/src/component/types.rs +++ b/crates/environ/src/component/types.rs @@ -469,6 +469,7 @@ impl ComponentTypesBuilder { self.core_outer_type(0, TypeIndex::from_u32(*ty)) } wasmparser::ComponentTypeRef::Func(ty) + | wasmparser::ComponentTypeRef::Type(_, ty) | wasmparser::ComponentTypeRef::Instance(ty) | wasmparser::ComponentTypeRef::Component(ty) => { self.component_outer_type(0, ComponentTypeIndex::from_u32(*ty)) @@ -476,9 +477,6 @@ impl ComponentTypesBuilder { wasmparser::ComponentTypeRef::Value(..) => { unimplemented!("references to value types"); } - wasmparser::ComponentTypeRef::Type(..) => { - unimplemented!("references to types"); - } } } diff --git a/crates/wasmtime/src/component/matching.rs b/crates/wasmtime/src/component/matching.rs index e5012a5043..ae38e3301a 100644 --- a/crates/wasmtime/src/component/matching.rs +++ b/crates/wasmtime/src/component/matching.rs @@ -72,6 +72,12 @@ impl TypeChecker<'_> { // the actual type. It's ok, though, to have extra exports in the actual // type. for (name, expected) in expected.exports.iter() { + // Interface types may be exported from a component in order to give them a name, but + // they don't have a definition in the sense that this search is interested in, so + // ignore them. + if let TypeDef::Interface(_) = expected { + continue; + } let actual = self .strings .lookup(name) diff --git a/tests/misc_testsuite/component-model/instance.wast b/tests/misc_testsuite/component-model/instance.wast index 74e5270122..d23fe605fa 100644 --- a/tests/misc_testsuite/component-model/instance.wast +++ b/tests/misc_testsuite/component-model/instance.wast @@ -179,6 +179,12 @@ )) ) +(component + (import "host" (instance $i + (type $rec (record (field "x" (record)) (field "y" string))) + (export "some-record" (type (eq $rec))))) +) + (component (import "host" (instance $i (export "nested" (instance