-
Notifications
You must be signed in to change notification settings - Fork 104
Description
Description
When a wasm-gc FFI stub function takes a closure (function type) as a parameter, the compiler rejects closures whose internal signature contains String, Array[T], or enum types with error [4042] Invalid stub type.
Closures passed to FFI stubs should be treated as opaque externref values on wasm-gc, regardless of their internal type signatures. The closure's parameter/return types are a MoonBit-level concern and should not affect the wasm import signature — the closure itself is just an externref.
Closures that work: those containing only #external types (externref) or wasm value types (Int, Double, UInt, etc.)
Closures that fail: those containing String, Array[T], or enum types as parameters or return types
Minimal Reproduction
moon.mod.json:
{
"name": "blem/closure-stub-bug",
"version": "0.1.0",
"moonc-opt": "v0.8.1"
}moon.pkg.json:
{
"is-main": true,
"supported-targets": ["wasm-gc"]
}main.mbt:
#external
pub type Event
#external
pub type EventListener
// --- These work (externref or wasm value types inside closure) ---
fn ok_externref(callback : (Event) -> Unit) -> EventListener = "m" "a"
fn ok_no_args(callback : () -> Unit) -> EventListener = "m" "b"
fn ok_int(callback : (Int) -> Unit) -> EventListener = "m" "c"
fn ok_double(callback : (Double) -> Unit) -> EventListener = "m" "d"
fn ok_ret_externref(callback : (Event) -> Event) -> EventListener = "m" "e"
// --- These fail with [4042] "Invalid stub type" ---
fn fail_string_param(callback : (String) -> Unit) -> EventListener = "m" "f"
fn fail_string_return(callback : (Event) -> String) -> EventListener = "m" "g"
fn fail_array_param(callback : (Array[Event]) -> Unit) -> EventListener = "m" "h"
fn main {
ignore(ok_externref)
ignore(ok_no_args)
ignore(ok_int)
ignore(ok_double)
ignore(ok_ret_externref)
ignore(fail_string_param)
ignore(fail_string_return)
ignore(fail_array_param)
}Actual behavior
$ moon build --target wasm-gc
Error: [4042]
fn fail_string_param(callback : (String) -> Unit) -> EventListener = "m" "f"
────────┬───────
╰───────── Invalid stub type.
Error: [4042]
fn fail_string_return(callback : (Event) -> String) -> EventListener = "m" "g"
────────┬────────
╰────────── Invalid stub type.
Error: [4042]
fn fail_array_param(callback : (Array[Event]) -> Unit) -> EventListener = "m" "h"
───────────┬──────────
╰──────────── Invalid stub type.
Expected behavior
All FFI stubs should compile successfully. The closure parameter is an externref on wasm-gc regardless of its internal type signature.
Environment
moonc -v: v0.8.1+bd827dc85 (2026-02-09)moon version: moon 0.1.20260209 (b129ae2 2026-02-09)- OS: Linux 6.18.7-arch1-1