Why this fires¶
as? and is ask the runtime a question, and the runtime can only answer
about what a value carries: its primitive category (int, str, bool,
nil, fn, table, array, map) or, for a user type, its declared name.
A structural shape such as [int], {str: int}, a record, a tuple, a union or
T? has no such witness — checking it would mean walking every element, which
neither backend does. Before this diagnostic existed the VM answered nil /
false and the native backend passed the value through untouched.
let payload: any = load()
let items = payload as? [int] // error[TE846]
if payload is {str: int} { ... } // error[TE846]Generic targets are accepted and probed by their base name: value as? Wrapper<int> checks for a Wrapper, and the type argument is not verified.
Fix it¶
Probe the category when the shape is all you need. The elements are not
verified, so the result is typed as the category, not as [int]:
let items = payload as? array
if payload is map { ... }Decode the value when the elements matter:
@derive(Deserialize)
struct Scores { values: [int] }
let scores = Scores.decode(payload)?For an optional target, probe the inner type and handle nil separately:
if payload == nil || payload is int { ... }