Skip to content

phase 8d: builtin.das push/emplace/push_clone/resize_and_init int|int64#2771

Merged
borisbat merged 3 commits into
masterfrom
bbatkin/longarr-builtin-int-int64-at
May 21, 2026
Merged

phase 8d: builtin.das push/emplace/push_clone/resize_and_init int|int64#2771
borisbat merged 3 commits into
masterfrom
bbatkin/longarr-builtin-int-int64-at

Conversation

@borisbat
Copy link
Copy Markdown
Collaborator

Summary

  • Closes the int-only gaps in daslib/builtin.das surface (push(at) / emplace(at) / push_clone(at) / resize_and_init) so caller code can reach insertion positions past INT_MAX. C++ runtime was already int64-capable since Phase 2+3 — only the daslang wrappers were narrow.
  • Each widened param is at : int | int64 with a static_if (typeinfo is_int(at)) body fork (zero-cost compile-time dispatch — int64 branch skips the int64(at) ExprCall entirely).
  • resize_and_init static_if also picks length/long_length, range/range64, and the matching __builtin_array_resize / _i64 so the int variant stays on the int-flavor SimNode path unchanged.

What changed

  • daslib/builtin.das:
    • push(at) (copy + move variants), emplace(at), push_clone(at) (copy + move variants), resize_and_init (both 1-arg and initValue variants) all widened to int | int64 + static_if dispatch.
    • Swept all 31 pre-existing lint warnings (STYLE024 / 025 / 026 / 005) — bundling per // nolint:STYLE025 … (6 clone variants where var x : T -# is conditionally unsafe — narrower scope than the var-decl is impossible).
  • doc/source/reference/language/generic_programming.rst — adds typeinfo is_int / is_int64 to the trait list (carry-over from phase 8b: typeinfo is_int / is_int64 + int|int64 disjunction spike #2764).
  • tests/long_array_table/test_int64_overloads.das — 5 new overload-resolution unit tests (push/emplace/push_clone at int64, resize_and_init int64 + initValue variant).
  • tests/long_array_table/test_huge_array_push_emplace_clone.das — extended with 3 huge-position probes (push/emplace/push_clone at insertion position past INT_MAX).
  • tests/long_array_table/test_huge_array_erase.das (NEW) — 2 probes for the already-widened erase(at:int64) / erase(at,count:int64) paths past INT_MAX. Same DASLANG_HUGE_HEAP_TESTS=1 gate as the rest of the dir.

Test plan

  • All 5 new overload-resolution tests fail on master (no matching overload) and pass on this branch
  • tests/long_array_table — 58/58 passing
  • tests/decs — 245/245 passing (heaviest user of push/emplace)
  • tests/linq — 1228/1228 passing
  • tests/daslib — 92/92 passing
  • tests/algorithm — 162/162 passing
  • Huge probes verified locally with DASLANG_HUGE_HEAP_TESTS=1 on a 2.2 GB uint8 array — push/emplace/push_clone at-position (3 tests, 1.3s) + erase + erase-range (2 tests, 0.8s) all PASS
  • dasfmt --verify clean on full tree (17470 files)
  • mcp__daslang__lint clean on daslib/builtin.das (was 31 hits → 0)

🤖 Generated with Claude Code

Closes the last int-only gaps in the daslib/builtin.das array surface
that prevent code from reaching insertion positions past INT_MAX. The
underlying C++ runtime (`__builtin_array_push` / `_push_zero` and
`__builtin_array_resize_i64`) has been int64-capable since the Phase 2+3
landings; only the daslang wrappers needed widening.

Widened (int -> int | int64 + static_if (typeinfo is_int(at)) dispatch,
so the int64 branch never pays an int64(at) ExprCall cost):
  * push(arr, value, at)               -- copy + move variants (lines 113, 126)
  * emplace(arr, var value, at)        -- line 224
  * push_clone(arr, value, at)         -- copy + move variants (lines 274, 287)
  * resize_and_init(arr, newSize)      -- + 2-arg initValue variant (lines 53, 69)

For resize_and_init, the static_if also picks the matching backing call
(__builtin_array_resize vs _i64), length() vs long_length(), range() vs
range64() -- the int variant stays on the int-flavor SimNode path
unchanged.

Tests:
  * tests/long_array_table/test_int64_overloads.das -- 5 new
    overload-resolution unit tests (push/emplace/push_clone at int64,
    resize_and_init int64 + initValue). Fails on master with "no matching
    overload"; passes here.
  * tests/long_array_table/test_huge_array_push_emplace_clone.das --
    extended with 3 huge insertion-path probes (push/emplace/push_clone
    at position > INT_MAX). Memory-gated on DASLANG_HUGE_HEAP_TESTS=1;
    verified locally on a 2.2 GB uint8 array (6 tests, 2.6s).
  * tests/long_array_table/test_huge_array_erase.das -- NEW. 2 probes
    for the already-widened erase(at:int64) / erase(at,count:int64)
    paths past INT_MAX. Same gate; verified locally (2 tests, 0.8s).

Side-effects:
  * doc/source/reference/language/generic_programming.rst -- adds
    typeinfo is_int / is_int64 to the trait list (carry-over from
    PR #2764 deferral).
  * daslib/builtin.das -- swept all 31 pre-existing lint warnings
    (STYLE024/025/026/005) per the bundling pattern. 6 of the clone /
    clone_to_move variants carry an explicit `// nolint:STYLE025` with
    the reason -- `var clone_dest : TT -#` is conditionally unsafe (the
    is_unsafe_when_uninitialized type set), and the unsafe block scope
    cannot be narrower than the var-decl.

Regression locally: 1785 tests pass across
  long_array_table (58) + decs (245) + linq (1228) + daslib (92) +
  algorithm (162). `dasfmt --verify` clean on full tree (17470 files).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 20, 2026 22:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR widens several daslib/builtin.das array helper APIs to accept insertion/resize positions beyond INT_MAX by changing the at/newSize parameters to int | int64 and using static_if (typeinfo is_int(...)) for compile-time dispatch. This aligns the daslang surface wrappers with the already-int64-capable C++ runtime paths and adds targeted tests + documentation updates.

Changes:

  • Widened push(at), emplace(at), push_clone(at), and resize_and_init to int | int64 with static_if dispatch to preserve the existing int fast-path.
  • Updated docs to list the typeinfo is_int / typeinfo is_int64 traits.
  • Added/extended tests/long_array_table coverage, including huge-heap probes gated by DASLANG_HUGE_HEAP_TESTS=1.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
daslib/builtin.das Adds `int
doc/source/reference/language/generic_programming.rst Documents typeinfo is_int / is_int64 traits.
tests/long_array_table/test_int64_overloads.das Adds overload-resolution tests to ensure int64 at/newSize calls bind correctly.
tests/long_array_table/test_huge_array_push_emplace_clone.das Extends huge-heap probes to cover int64 insertion positions past INT_MAX.
tests/long_array_table/test_huge_array_erase.das New huge-heap probes for existing int64 erase overloads past INT_MAX.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/long_array_table/test_huge_array_erase.das
borisbat and others added 2 commits May 20, 2026 15:49
…andmade

Two CI failures from the initial PR-builtin commit:

1. tests/language/lock_array.das fails on darwin26/darwin15/linux_arm and
   wasm with `error[31000]: address of reference requires unsafe` at
   daslib/builtin.das lock_data. The STYLE025 sweep narrowed
   `unsafe { invoke(blk, reinterpret<TT?#> addr(a[0]), len) }` to
   `invoke(blk, unsafe(reinterpret<TT?#> addr(a[0])), len)`, but `addr()`
   needs its own unsafe context too -- the lint's STYLE025 leaf detection
   doesn't recognize addr() as an unsafe op, so the rule fires on what is
   actually a 2-unsafe-leaf block (justified). Reverted both lock_data
   variants (var + non-var arrays) back to block form with `// nolint:
   STYLE025` and the reason. The empty-array null branch keeps the
   narrowed `unsafe(reinterpret<...> null)` since no addr is involved.

   Caught locally by `dastest -- --test tests/language`. Pre-push only
   ran tests/long_array_table + tests/decs + tests/linq + tests/daslib +
   tests/algorithm and missed lock_array which lives under tests/language
   -- expanded local pre-push test scope going forward.

2. `Check for // stub in handmade docs` CI step found a new stub at
   doc/source/stdlib/handmade/function-builtin-resize_and_init-0xba1d8e
   a89988acec.rst. The int|int64 widening changed the canonical signature
   hash so das2rst.das emitted a fresh stub. Per the documentation_rst
   skill, daslib uses handmade-flow for per-symbol docs -- filled the
   stub with the same 1-line description as the prior int-only hashes
   (default-init resize). The 2-arg `initValue` variant continued to
   resolve to its existing handmade file (unchanged hash).

Verified locally:
  * lint clean on daslib/builtin.das (0 warnings)
  * tests/language -- 1003/1003 pass (was 1 error on master + this PR)
  * tests/long_array_table -- 58/58 pass
  * das2rst.das -- no stubs remaining

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…y skipped

The pre-push hook runs `daslang utils/lint/main.das -- <changed> --quiet`
on every changed `.das` file. `utils/lint/main.das:88` hard-codes
`daslib/builtin.das` to the `is_skip_file` set (lint can't compile it
standalone; it's parsed as the implicit-prelude module).

Before this fix: if the only changed `.das` is `daslib/builtin.das`,
`scan_das_files` skips it, `files` ends empty, lint exits 1 with
"Error: no .das files found". That's a false negative -- the user
DID nothing wrong; the skip-list filtered out the only input.

After this fix: `scan_das_files` tracks `var skipped : int&`. If
`files` is empty at the end AND `skipped > 0`, lint exits 0 silently.
If `files` is empty AND `skipped == 0` (genuine "no .das at the
path"), the original error path stays.

Caught while pushing part 2/N of PR #2771 -- the only changed `.das`
was `daslib/builtin.das` and pre-push refused to push despite local
verification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@borisbat borisbat merged commit 3d37189 into master May 21, 2026
28 checks passed
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.

2 participants