Open CharlieTap opened 3 weeks ago
This simply verifies that (ref.null any) and (ref.null none) are the same value. There is no type matching involved, neither dynamically nor statically (the script level is pretty much untyped).
I guess I'm not following 🤔 , how could two different types be the same value? Irrespective of language and encoding you're going to have some composition of structs and the inner (abstract heap type) none would not equal any without some additional type matching logic?
Well, both variants of the null instructions produce the same null value. There exists only one null value (per type hierarchy anyway, across hierarchies they are incomparable so you can't tell). The heaptype annotation primarily exists to determine the type hierarchy. Within a given hierarchy the specific annotation only affects the local static type of the null value, not its representation. You can always pick the respective bottom type — the fact that you can choose others is a historical wart more than anything else.
For other heap types, like struct or array, ref patterns indeed requires some minimal matching logic. It is fair to view this as runtime subtyping if you prefer, but in a very limited form that really only amounts to classifying GC values into structs, array, i31s, and null. Depending on the implementation, these are typically distinguished by other mechanisms than actual runtime types. In particular, subtype declarations are never relevant for testing this.
Various test assertions require the testsuite runner implementation to understand the type matching logic, for example:
Any code computing assert_return would need to understand that
ref.null any
matchesref.null none
, which is a little odd as now the test itself is dependant on working matching code. Ideally the test assertions would simply be testing equality, and the actual wasm code would perform a computation that proves the type matching is correct. Thoughts?