backend: == on two concrete stack values fails to compile #209
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Finding
Found by the loop worker for #198 (PR #202):
a == bwhere both sides are concreteArrayStack<Int>(and likewiseConsStack<Int>) fails in the backend. Comparing throughStack<Int>-typed parameters works, so the conformance program in #202 uses that workaround.Goal
Structural equality on concrete stack (and other collection) types compiles and behaves like the trait-typed comparison.
Next
Refine: reproduce on main, locate the failing backend step, write acceptance criteria. Seed impact unknown until refined.
Same family, found by the #199 worker (PR #203):
==between twoQueuevalues (incl.ArrayQueue) hits an internal VM error; the conformance program compares throughtoList()instead. Scope of this issue: structural==on concrete collection values (stacks, queues) in VM and backend.Same family, found by the #197 worker (PR #201):
==between two concreteListimplementation values (e.g.RingList) fails in lowering; predates that PR.[loop:torbscript] intake: in scope (finding from the loop worker of PR #202, author orion, label
loop), no duplicate among the open issues, no collision with a design record seen at triage; a backend defect on concrete collection types, seed impact unknown until refined, next: refine (queued behind the ready buffer, waiting until the buffer drops below 4readyissues)[loop:torbscript] refine: held back, the ready buffer is above its target of 4
readyissues, next: waiting (ready buffer full)[loop:torbscript] claim refine by session:loop-torbscript-20261012 until 2026-10-12T13:05Z
[loop:torbscript] decided by the loop: refined from a read of the code (no local build: gates and bootstraps run in forge CI only).
Cause (hypothesis to confirm first in CI):
Equalsfor every stack, queue and list is declared as an extension of the trait (extend<Item: Equals> Stack<Item> with Equals, std/collections/src/stack.trb:84; likewiseQueuein queue.trb:84 andListin list.trb:488).a == blowers toEquals.equalsthroughlowerOperator(compiler/src/ir/lower/call.trb:1959, vialowerOperatorExpressionin ir/lower/expression.trb:1509). With both operands typed as the trait it resolves; with a concrete implementation type (ArrayStack<Int>,ConsStack<Int>,RingList,ArrayQueue) the trait-extension member is not found or its receiver is not coerced (receiverOfTraitExtension, call.trb:287). The VM error onQueueand the lowering failure onListare the same family; the issue covers all concrete collection types, not only stacks.Goal:
a == banda != bon two values of the same concrete collection type (stacks, queues, lists) compile and run in the VM and--native, with exactly the result of the trait-typed comparison.Acceptance criteria
tests/conformance/concrete-collection-equality.trb(+.expected) compares, with==and!=and noStack/Queue/List-typed helper: twoArrayStack<Int>, twoConsStack<Int>, twoArrayQueue<Int>, twoBankersQueue<Int>, twoRingList<Int>: equal, different length, different order, empty vs empty. Tier B runs it in the VM and native with identical output.samehelper intests/conformance/cons-stack-persists.trband thetoList()comparisons in the queue conformance program) and still print the same output.compiler/testscovers the lowering of==with concrete collection operands (fails onmain, passes after).ArrayStack == ConsStack) stay a checker error as today, becauseEquals.equalstakesSelf(CLOSED-TRAITS.md section on==); no behaviour change there.sh tools/gates.sh abgreen in forge CI.Design link: docs/design/COLLECTIONS.md (collections are
Equalswhen their items are;Item: Equalsbound) and docs/design/CLOSED-TRAITS.md 7.5. Roadmap: milestone row "collections" in docs/ROADMAP.md (related open item #212). No design record changes; the language rule already says this must work.Seed impact: none expected. This is a fix inside the checker/lowering (compiler/src), with no new syntax, native, driver flag or renamed std name looked up by string, so one commit
fix(ir): ...(plus its test and the conformance program) suffices. If the fix turns out to need a std rename or a new well-known name, the worker stops and splits it per the two-commit rule instead.Size: one PR, one or two Conventional Commits (
fix(ir)for the lowering,test(conformance)for the program and cleanup). Implementer: opus/high (compiler/src/ir). First step for the worker: reproduce with a scratch program in CI and confirm the failing step before changing code.[loop:torbscript] refine: ready (goal, acceptance criteria incl. regression tests, design link, seed impact none expected, one PR), label
readyset, next: implement. Tokens: ~60k (sonnet worker, read-only analysis).[loop:torbscript] claim implement by session:loop-torbscript-20261012 until 2026-10-12T17:07Z