Expose List.capacity function - #10823
Conversation
Greptile SummaryExposes
Confidence Score: 4/5The PR should not merge until The newly exposed builtin returns the list length in evaluation but zero through LLVM for the same nonempty zero-width list, violating its documented capacity invariant. Files Needing Attention: src/canonicalize/BuiltinLowLevel.zig, src/build/roc/Builtin.roc, and the backend-focused capacity tests
|
| Filename | Overview |
|---|---|
| src/build/roc/Builtin.roc | Adds the public declaration and an invariant that LLVM does not satisfy for nonempty zero-width-element lists. |
| src/canonicalize/BuiltinLowLevel.zig | Exposes the existing .list_capacity backend discrepancy through the public builtin. |
| src/eval/test/eval_low_level_tests.zig | Adds a positive reserved-capacity test but does not exercise zero-width lists or cross-backend consistency. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A["Builtin.List.capacity(list)"] --> B["Canonicalize to .list_capacity"]
B --> C{"Backend"}
C --> D["Evaluator: max(stored capacity, len)"]
C --> E["LLVM: decode stored capacity"]
F["Nonempty zero-width list\nlen = N, stored capacity = 0"] --> D
F --> E
D --> G["Returns N"]
E --> H["Returns 0"]
Reviews (1): Last reviewed commit: "Expose List.capacity across backends" | Re-trigger Greptile
| if (env.common.findIdent("Builtin.List.capacity")) |list_cap_ident| { | ||
| try low_level_map.put(list_cap_ident, .list_capacity); | ||
| } |
There was a problem hiding this comment.
Zero-width capacity diverges by backend
When List.capacity is called on a nonempty zero-width-element list such as [(), (), ()], this mapping exposes .list_capacity, for which LLVM returns the stored capacity of 0 while evaluation returns the list length. This violates the documented capacity >= len invariant and makes the same Roc program return different results across backends.
This PR exposes the
List.capacitybuiltin (mentioned in #9596)