Skip to content

Expose List.capacity function - #10823

Open
samnaughtonb wants to merge 1 commit into
roc-lang:mainfrom
samnaughtonb:feat/add-list-capacity
Open

Expose List.capacity function#10823
samnaughtonb wants to merge 1 commit into
roc-lang:mainfrom
samnaughtonb:feat/add-list-capacity

Conversation

@samnaughtonb

@samnaughtonb samnaughtonb commented Aug 16, 2026

Copy link
Copy Markdown

This PR exposes the List.capacity builtin (mentioned in #9596)

@samnaughtonb samnaughtonb changed the title Expose List.capacity across backends Expose List.capacity function Aug 16, 2026
@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Exposes List.capacity as a public builtin by mapping it to the existing low-level operation and adds an evaluator test.

  • Adds the List.capacity : List(_item) -> U64 declaration and documentation.
  • Registers the declaration with canonicalization as .list_capacity.
  • Tests reserved capacity for a List(U64).

Confidence Score: 4/5

The PR should not merge until List.capacity reports a contract-compliant, backend-consistent value for nonempty zero-width-element lists.

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

Important Files Changed

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"]
Loading

Reviews (1): Last reviewed commit: "Expose List.capacity across backends" | Re-trigger Greptile

Comment on lines +298 to +300
if (env.common.findIdent("Builtin.List.capacity")) |list_cap_ident| {
try low_level_map.put(list_cap_ident, .list_capacity);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant