Description
TL;DR: I suggest dropping the check that all br_table
targets have equal types (which will become more complicated in the presence of subtyping), and instead check that stack values are compatible with every target.
First of all, thanks for this proposal. As an engine implementor, I think it will make decoding simpler, especially given the upcoming proposals which complicate the type system.
To the matter at hand: the br_table
typing rule states that label_types(ctrls[n]) != label_types(ctrls[m])
. This is chosen over typechecking against each label to cover the following situation in unreachable code:
(block i32 (block i64 (unreachable) (i32.const 42) (br_table 0 1 0)))
should not validate, because, even though every individual label would be fine in a polymorphic stack environment, there is no value that could simultaneously type check against all labels.
However, given upcoming proposals which introduce subtyping, this computation is not as simple as checking for label type equality. Instead we need to compute that the greatest common subtype (GCS) of all label types is not bottom. This, however is not as simple: In the GC proposal, consider the types (ref null t1)
and (ref t2)
where t1 <: t2
. Their GCS is (ref t1)
which is neither of these types. Implementing the GCS algorithm correctly will take a few hundreds of lines of code, and will be only useful for technicality in unreachable code.
Therefore, I suggest to switch to checking that stack values typecheck against the type of each individual label (which is trivially true in unreachable code).