Summary
The dynamic dispatch infrastructure lowers WitnessTableIDType and RTTIHandleType to uint2 (vector of 2×uint32) in slang-ir-lower-dynamic-dispatch-insts.cpp:1607-1634. This works on SPIRV/CUDA/CPU where uint2 can be bitcast to a 64-bit pointer, but fails on Metal because MSL does not allow vector-to-pointer casts.
Error
When enabling Metal on tests that use interface/existential pointers (e.g. tests/language-feature/dynamic-dispatch/buffer-address-ref.slang):
metal error: cannot cast from type 'uint2' (vector of 2 'unsigned int' values) to pointer type 'device Tuple_0 *'
Root cause
lowerHandleTypes() in slang-ir-lower-dynamic-dispatch-insts.cpp unconditionally replaces WitnessTableID and RTTIHandle types with uint2. The uint2 was chosen to avoid Int64 capability requirements (PR #9386). However, Metal fully supports Int64 (ulong) and requires scalar types for pointer casts.
Proposed fix
Option A (emitter-level): In slang-emit-metal.cpp, when emitting a cast from uint2 to a pointer type, emit a two-step cast: as_type<ulong>(uint2Value) then (device T*)ulongValue.
Option B (IR-level): On Metal targets, lower handles to ulong instead of uint2 in lowerHandleTypes(). Metal has Int64 support, so the "avoid Int64" concern doesn't apply.
Context
Found while investigating whether tests/language-feature/dynamic-dispatch/buffer-address-ref.slang could be enabled for Metal as part of PR #10947 (Metal pointer-to-pointer lowering).
Related: #9828 (dynamic dispatch quality umbrella)
Summary
The dynamic dispatch infrastructure lowers
WitnessTableIDTypeandRTTIHandleTypetouint2(vector of 2×uint32) inslang-ir-lower-dynamic-dispatch-insts.cpp:1607-1634. This works on SPIRV/CUDA/CPU whereuint2can be bitcast to a 64-bit pointer, but fails on Metal because MSL does not allow vector-to-pointer casts.Error
When enabling Metal on tests that use interface/existential pointers (e.g.
tests/language-feature/dynamic-dispatch/buffer-address-ref.slang):Root cause
lowerHandleTypes()inslang-ir-lower-dynamic-dispatch-insts.cppunconditionally replaces WitnessTableID and RTTIHandle types withuint2. Theuint2was chosen to avoid Int64 capability requirements (PR #9386). However, Metal fully supports Int64 (ulong) and requires scalar types for pointer casts.Proposed fix
Option A (emitter-level): In
slang-emit-metal.cpp, when emitting a cast fromuint2to a pointer type, emit a two-step cast:as_type<ulong>(uint2Value)then(device T*)ulongValue.Option B (IR-level): On Metal targets, lower handles to
ulonginstead ofuint2inlowerHandleTypes(). Metal has Int64 support, so the "avoid Int64" concern doesn't apply.Context
Found while investigating whether
tests/language-feature/dynamic-dispatch/buffer-address-ref.slangcould be enabled for Metal as part of PR #10947 (Metal pointer-to-pointer lowering).Related: #9828 (dynamic dispatch quality umbrella)