Problem
Value-copy ($value_copy$) helpers and array-clone element helpers are identified by a structural name mangle (TypeTable::mangle_type_arg_for_generic) instead of by a canonical type identity. This compensates for the TypeTable interning the same logical type under multiple TypeIds:
- A
GenericInstance and its monomorphized Struct coexist as distinct ids — monomorphization mints a new Struct id and leaves the GenericInstance id live (linkage is kept in Monomorphizer.type_substitutions, not in the table).
List<T> / tuples intentionally stay GenericInstance, so they get a fresh id whenever their argument ids diverge.
Because there is no canonical TypeId, several passes independently re-derive the mangle to key/root the same helper:
lower/plan/value_copy/synthesize.rs — names the helper
wir_build/functions.rs, wir_build/calls.rs — stamp value_copy_mangle / element_copy_mangle
optimize/dce.rs — NIR DCE rooting
wir_optimize/dce.rs, wir_optimize/util.rs — WIR DCE rooting / SROA pinning
codegen/emit.rs — ArrayClone resolution
Why it matters
- Correctness fragility. A helper's definition and its references derive identity from independent mangle computations that must agree byte-for-byte. If the mangle is not injective, distinct types collapse onto one helper and the pipeline emits an invalid Wasm module. For example, a bare
Array<Foo> whose element Foo is a same-named struct from two different modules collapses onto a single helper whose one concrete signature then mismatches the other array's ref type. Other collision vectors are plausible.
- Altitude. Structural identity is re-derived at ~6 sites rather than assigned once.
- Cost. Allocating, recursive string mangling on rooting and codegen paths.
Direction
Give value-copy helpers a single, assigned-once canonical identity that consumers reference by id, with the structural key computed in exactly one authority.
One load-bearing constraint to respect: the mangle is robust because it is a pure function of structure — an unseen duplicate TypeId still resolves correctly. Any replacement must preserve that property, or eliminate the duplicate interning it compensates for. Note that some of the duplication is intentional (List/tuple staying GenericInstance; monomorphization needing to see raw GenericInstances), so removing duplicate interning is not automatically the answer.
The above is only one example. This should be approached from a zero base and designed for the best long-term maintainability, not anchored to this sketch.
Problem
Value-copy (
$value_copy$) helpers and array-clone element helpers are identified by a structural name mangle (TypeTable::mangle_type_arg_for_generic) instead of by a canonical type identity. This compensates for theTypeTableinterning the same logical type under multipleTypeIds:GenericInstanceand its monomorphizedStructcoexist as distinct ids — monomorphization mints a newStructid and leaves theGenericInstanceid live (linkage is kept inMonomorphizer.type_substitutions, not in the table).List<T>/ tuples intentionally stayGenericInstance, so they get a fresh id whenever their argument ids diverge.Because there is no canonical
TypeId, several passes independently re-derive the mangle to key/root the same helper:lower/plan/value_copy/synthesize.rs— names the helperwir_build/functions.rs,wir_build/calls.rs— stampvalue_copy_mangle/element_copy_mangleoptimize/dce.rs— NIR DCE rootingwir_optimize/dce.rs,wir_optimize/util.rs— WIR DCE rooting / SROA pinningcodegen/emit.rs—ArrayCloneresolutionWhy it matters
Array<Foo>whose elementFoois a same-named struct from two different modules collapses onto a single helper whose one concrete signature then mismatches the other array's ref type. Other collision vectors are plausible.Direction
Give value-copy helpers a single, assigned-once canonical identity that consumers reference by id, with the structural key computed in exactly one authority.
One load-bearing constraint to respect: the mangle is robust because it is a pure function of structure — an unseen duplicate
TypeIdstill resolves correctly. Any replacement must preserve that property, or eliminate the duplicate interning it compensates for. Note that some of the duplication is intentional (List/tuple stayingGenericInstance; monomorphization needing to see rawGenericInstances), so removing duplicate interning is not automatically the answer.The above is only one example. This should be approached from a zero base and designed for the best long-term maintainability, not anchored to this sketch.