Repository: bytecodealliance/wasm-tools
Pull request #2094 (2025-03-11 18:26:02)

`wasmparser`: add a hint to out-of-bounds type indices errors
When an out-of-bounds type index would be in bounds if the GC proposal was enabled, but it is not, add some extra verbiage to the error message explaining that. This is useful for people who are playing around with Wasm GC in Wasmtime, but forget to enable it on the CLI or in their config.

I've taken care to only *add* to the error message, so that the substring matching we use for `.wast` tests will continue to work.


Patch:
diff --git a/crates/wasmparser/src/validator/core/canonical.rs b/crates/wasmparser/src/validator/core/canonical.rs
index b109eb75..67f6a94c 100644
--- a/crates/wasmparser/src/validator/core/canonical.rs
+++ b/crates/wasmparser/src/validator/core/canonical.rs
@@ -388,14 +388,21 @@ impl<'a> TypeCanonicalizer<'a> {
                 // typed function references proposal, only the GC proposal.
                 debug_assert!(self.allow_gc() || self.rec_group_len == 1);
                 let local = index - self.rec_group_start;
-                if self.allow_gc() && local < self.rec_group_len {
-                    if let Some(id) = PackedIndex::from_rec_group_index(local) {
-                        *ty = id;
-                        return Ok(());
+                if local < self.rec_group_len {
+                    if self.allow_gc() {
+                        if let Some(id) = PackedIndex::from_rec_group_index(local) {
+                            *ty = id;
+                            return Ok(());
+                        } else {
+                            bail!(
+                                self.offset,
+                                "implementation limit: too many types in a recursion group"
+                            )
+                        }
                     } else {
                         bail!(
                             self.offset,
-                            "implementation limit: too many types in a recursion group"
+                            "unknown type {index}: type index out of bounds because the GC proposal is disabled"
                         )
                     }
                 }


Test patch:
diff --git a/tests/local/missing-features/function-references/hint.wast b/tests/local/missing-features/function-references/hint.wast
new file mode 100644
index 00000000..74b15d1a
--- /dev/null
+++ b/tests/local/missing-features/function-references/hint.wast
@@ -0,0 +1,5 @@
+(assert_invalid
+  (module
+    (type $ty (func (param (ref null $ty))))
+  )
+  "unknown type 0: type index out of bounds because the GC proposal is disabled")
diff --git a/tests/snapshots/local/missing-features/function-references/hint.wast.json b/tests/snapshots/local/missing-features/function-references/hint.wast.json
new file mode 100644
index 00000000..50b16244
--- /dev/null
+++ b/tests/snapshots/local/missing-features/function-references/hint.wast.json
@@ -0,0 +1,12 @@
+{
+  "source_filename": "tests/local/missing-features/function-references/hint.wast",
+  "commands": [
+    {
+      "type": "assert_invalid",
+      "line": 2,
+      "filename": "hint.0.wasm",
+      "module_type": "binary",
+      "text": "unknown type 0: type index out of bounds because the GC proposal is disabled"
+    }
+  ]
+}
\ No newline at end of file