Skip to content

fix: an Array literal of numbers is numeric storage for the Add proof only while its elements are only read - #14586

Merged
proggeramlug merged 3 commits into
mainfrom
fix/literal-array-sum-proof
Nov 12, 2026
Merged

proggeramlug merged 3 commits into
mainfrom
fix/literal-array-sum-proof

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

let t: any = 0; for (..) t = t + a[i] over const a = [1, 2, 3] after (a as any)[1] = "two" printed 1two (node
1two3). Tier: collectors/ptr_shape_numeric.rs numeric_view_value_or_undefined (the Add rule of the
Number-by-construction fixpoint, #8302) took a local whose stable initializer is an Array literal of numbers as numeric
storage whatever the body did with it, so t was a Number by construction (number_by_construction_locals), the
guarded add (expr/binary.rs) did not test t, and its numeric arm fadded the NaN-boxed string, whose payload
survived the add. No fact was false (check mode clean): a codegen proof.

  • retain_unwritten_literal_arrays: a candidate stays numeric storage only while every use of the local in the body
    (closure bodies and a region's loop control included) is an element read or a length read; applied to the
    fixpoint's stable initializers and to the Ptr<Shape> walk's const initializers (the field-numeric claim uses the
    same rule).
  • Switch PERRY_LITERAL_ARRAY_WRITE_CHECK=0 = main (registered in compile_env). Chess IR and binary byte-identical on vs
    off (the rule never fires on chess).
  • Fixture tests/parity/language/array/test_literal_array_sum_after_store.ts (store via as any, push, alias, call,
    closure, fill, the same loop before and after a store; controls: untouched literal, numeric store, typed array, out
    of bounds): on MATCH default and check mode; off and main 2 lines differ (1two 6four 0x 0w 12c 1f).
  • Unit test literal_array_sum_loses_its_proof_to_an_element_store (ptr_shape_group_numeric_tests).
  • Chess: table above. Full-corpus check mode (2 657 programs, stacked build w2 = w1 + the Map / Set brand PR): rc 86 = exactly
    temporal/test_gap_temporal_keyed_read_chain and object/test_vr_replacer_hole_main (expected); the same 5 compile
    failures as main. Not run: IR census, tssrc, Supabase, skin size, full suites, test262.

Measurement

Common measurement (qb10, perf stat -e instructions:u, taskset -c 30): build m0 = main bee9504 (merge base), build w1 =
bee9504 + PR A (delete) + PR C (Reflect.construct) + PR D (literal array) stacked, head b729f1b7f9; the PRs were then
merged with main 4a36321 (no conflicts in their files' hunks).

| chess (M instr) | search 250000 | perft 4 | evaluate 100000 | legal 10000 |
|

@coderabbitai

coderabbitai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Explain Change →

Caution

Review failed

The pull request is closed.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@proggeramlug
proggeramlug merged commit f871f50 into main Nov 12, 2026
92 of 102 checks passed
@proggeramlug
proggeramlug deleted the fix/literal-array-sum-proof branch November 12, 2026 23:47
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