Repository: bytecodealliance/wasm-tools (rust)

Issue:
wit-component: static Resource function causes Validate to fail
Per the Zulip [discussion](https://bytecodealliance.zulipchat.com/#narrow/stream/206238-general/topic/wasmparser.20assumptions.20about.20Resources.20with.20static.20functions) this afternoon, 

this is opened against wasm-tools. The original [issue](https://github.com/bytecodealliance/cargo-component/issues/284), against `cargo-component`, included the zip file to allow easy reproduction of the problem.

The importer.wasm file that is created seems to be the raw wasm file: 
[importer.wasm.gz](https://github.com/bytecodealliance/wasm-tools/files/15203467/importer.wasm.gz)

And here is the command line that could reproduce the problem.
```
wasm-tools component new ~/Downloads/importer.wasm --adapt ./wasi_snapshot_preview1.reactor.wasm
```

The error message:
```
error: failed to encode a component from module

Caused by:
    0: failed to validate component output
    1: export name `[static]my-resource.get-static` is not valid
       static resource name is not known in this context (at offset 0xb)
```

Pull request:
Fix creating components with only static methods on resources
Previously the resource itself wasn't imported which meant that the `[static]` function did not pass validation. This commit updates the liveness of these functions to include the resource that the static function is attached to which ensures that the type is emitted during component construction.

Closes #1529

Patch:
diff --git a/crates/wit-parser/src/live.rs b/crates/wit-parser/src/live.rs
index 19ded915..ee9b7855 100644
--- a/crates/wit-parser/src/live.rs
+++ b/crates/wit-parser/src/live.rs
@@ -1,4 +1,6 @@
-use crate::{Function, InterfaceId, Resolve, Type, TypeDefKind, TypeId, WorldId, WorldItem};
+use crate::{
+    Function, FunctionKind, InterfaceId, Resolve, Type, TypeDefKind, TypeId, WorldId, WorldItem,
+};
 use indexmap::IndexSet;
 
 #[derive(Default)]
@@ -41,6 +43,19 @@ impl LiveTypes {
     }
 
     pub fn add_func(&mut self, resolve: &Resolve, func: &Function) {
+        match func.kind {
+            // This resource is live as it's attached to a static method but
+            // it's not guaranteed to be present in either params or results, so
+            // be sure to attach it here.
+            FunctionKind::Static(id) => self.add_type_id(resolve, id),
+
+            // The resource these are attached to is in the params/results, so
+            // no need to re-add it here.
+            FunctionKind::Method(_) | FunctionKind::Constructor(_) => {}
+
+            FunctionKind::Freestanding => {}
+        }
+
         for (_, ty) in func.params.iter() {
             self.add_type(resolve, ty);
         }


Test patch:
diff --git a/crates/wit-component/tests/components/import-only-resource-static-function/component.wat b/crates/wit-component/tests/components/import-only-resource-static-function/component.wat
new file mode 100644
index 00000000..3c5b02e6
--- /dev/null
+++ b/crates/wit-component/tests/components/import-only-resource-static-function/component.wat
@@ -0,0 +1,30 @@
+(component
+  (type (;0;)
+    (instance
+      (export (;0;) "a" (type (sub resource)))
+      (type (;1;) (func))
+      (export (;0;) "[static]a.f" (func (type 1)))
+    )
+  )
+  (import "foo:bar/x" (instance (;0;) (type 0)))
+  (core module (;0;)
+    (type (;0;) (func))
+    (import "foo:bar/x" "[static]a.f" (func (;0;) (type 0)))
+    (@producers
+      (processed-by "wit-component" "$CARGO_PKG_VERSION")
+      (processed-by "my-fake-bindgen" "123.45")
+    )
+  )
+  (alias export 0 "[static]a.f" (func (;0;)))
+  (core func (;0;) (canon lower (func 0)))
+  (core instance (;0;)
+    (export "[static]a.f" (func 0))
+  )
+  (core instance (;1;) (instantiate 0
+      (with "foo:bar/x" (instance 0))
+    )
+  )
+  (@producers
+    (processed-by "wit-component" "$CARGO_PKG_VERSION")
+  )
+)
diff --git a/crates/wit-component/tests/components/import-only-resource-static-function/component.wit.print b/crates/wit-component/tests/components/import-only-resource-static-function/component.wit.print
new file mode 100644
index 00000000..d336e574
--- /dev/null
+++ b/crates/wit-component/tests/components/import-only-resource-static-function/component.wit.print
@@ -0,0 +1,5 @@
+package root:component;
+
+world root {
+  import foo:bar/x;
+}
diff --git a/crates/wit-component/tests/components/import-only-resource-static-function/module.wat b/crates/wit-component/tests/components/import-only-resource-static-function/module.wat
new file mode 100644
index 00000000..87ca6287
--- /dev/null
+++ b/crates/wit-component/tests/components/import-only-resource-static-function/module.wat
@@ -0,0 +1,3 @@
+(module
+  (import "foo:bar/x" "[static]a.f" (func))
+)
diff --git a/crates/wit-component/tests/components/import-only-resource-static-function/module.wit b/crates/wit-component/tests/components/import-only-resource-static-function/module.wit
new file mode 100644
index 00000000..39b390ff
--- /dev/null
+++ b/crates/wit-component/tests/components/import-only-resource-static-function/module.wit
@@ -0,0 +1,11 @@
+package foo:bar;
+
+interface x {
+  resource a {
+    f: static func();
+  }
+}
+
+world module {
+  import x;
+}