← board

ABI oracle: backends consult it, and stop reading Syms[]

Design: devdocs/dev/type-identity-as-substrate.md item 4. Depends on [[feature-a-typeref-handle]].

The break being fixed

IRTk is a bare kind and identity rides IRA/IRB/IRC positionally per opcode. That is not enough to emit code, so backends reach around the IR into frontend data:

(Syms[symIdx].Kind = skParam) and (Syms[symIdx].IsRef or ...)

The IR claims to be the substrate but a backend cannot be written against the IR alone.

Shape

A per-target oracle answers PassBy(t) / ReturnVia(t) / SlotHoldsPointer(t). Backends consult the oracle and never touch Syms[] — that clause is the enforceable invariant, and is greppable in review.

Cleans up

The "param slot holds a pointer" rule is written 8 times and 3 copies disagree (see [[bug-a-param-pointer-rule-divergence]]). AN_CALL and AN_VIRTUAL_CALL decide returns independently, which is why a def returning str works and a method crashes ([[bug-nilpy-method-returning-str-garbage]]).

CAUTION: RetViaHiddenDest does NOT cover tyAnsiString — a managed string returns a heap handle in a register. The oracle must not assume "aggregate" == "hidden dest".

Success metric

Adding one new pass-by-pointer / return-via-dest type kind currently needs edits at 9 independent sites. After this it must need one. If it still takes six backend edits, this failed regardless of how clean it reads.