alexcrichton opened issue #15036:
This test:
(module $M (type $t (func (result i32))) (table (export "t") 2 funcref) (table (export "a") 2 anyref) (func (export "call") (param i32) (result i32) (call_indirect (type $t) (local.get 0))) (func (export "get-a") (param i32) (result i32) (i31.get_s (ref.cast (ref i31) (table.get 1 (local.get 0)))))) (register "M" $M) (assert_trap (module (type $a (array (mut i64))) (import "M" "t" (table 2 funcref)) (table $t2 1 anyref) (func $f (result i32) (i32.const 7)) (elem (table 0) (i32.const 0) func $f) (elem (table $t2) (i32.const 0) anyref (array.new_default $a (i32.const 0x7fffffff)))) "allocation size too large") (assert_trap (invoke $M "call" (i32.const 0)) "uninitialized element")fails with:
$ cargo run -- wast foo.wast Error: failed to run script file 'foo.wast' Caused by: 0: failed directive on foo.wast:21 1: expected trap, got Core([I32(7)])and the same with the trap in a later element of the same segment:
(assert_trap (module (type $a (array (mut i64))) (import "M" "a" (table 2 anyref)) (elem (table 0) (i32.const 0) anyref (ref.i31 (i32.const 5)) (array.new_default $a (i32.const 0x7fffffff)))) "allocation size too large") (assert_trap (invoke $M "get-a" (i32.const 0)) "null reference")$ cargo run -- wast foo.wast Error: failed to run script file 'foo.wast' Caused by: 0: failed directive on foo.wast:19 1: expected trap, got Core([I32(5)])The spec's instantiation evaluates the element expressions of every segment before running any active segment's
table.init, so a trapping expression should leave imported tables untouched.Fixing this in my opinion is going to need to be balanced with implementation complexity. This is a vanishingly niche use case which in theory shouldn't come along with a large implementation burden. Nevertheless I figured it's worth opening here.
alexcrichton added the bug label to Issue #15036.
Last updated: Oct 31 2026 at 23:03 UTC