phase 8d: builtin.das push/emplace/push_clone/resize_and_init int|int64#2771
Merged
Conversation
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>
Contributor
There was a problem hiding this comment.
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), andresize_and_inittoint | int64withstatic_ifdispatch to preserve the existing int fast-path. - Updated docs to list the
typeinfo is_int/typeinfo is_int64traits. - Added/extended
tests/long_array_tablecoverage, including huge-heap probes gated byDASLANG_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.
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
daslib/builtin.dassurface (push(at)/emplace(at)/push_clone(at)/resize_and_init) so caller code can reach insertion positions pastINT_MAX. C++ runtime was already int64-capable since Phase 2+3 — only the daslang wrappers were narrow.at : int | int64with astatic_if (typeinfo is_int(at))body fork (zero-cost compile-time dispatch — int64 branch skips theint64(at)ExprCallentirely).resize_and_initstatic_if also pickslength/long_length,range/range64, and the matching__builtin_array_resize/_i64so 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 andinitValuevariants) all widened toint | int64+ static_if dispatch.// nolint:STYLE025 …(6 clone variants wherevar x : T -#is conditionally unsafe — narrower scope than the var-decl is impossible).doc/source/reference/language/generic_programming.rst— addstypeinfo is_int/is_int64to 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_cloneat int64,resize_and_initint64 + initValue variant).tests/long_array_table/test_huge_array_push_emplace_clone.das— extended with 3 huge-position probes (push/emplace/push_cloneat insertion position pastINT_MAX).tests/long_array_table/test_huge_array_erase.das(NEW) — 2 probes for the already-widenederase(at:int64)/erase(at,count:int64)paths pastINT_MAX. SameDASLANG_HUGE_HEAP_TESTS=1gate as the rest of the dir.Test plan
no matching overload) and pass on this branchtests/long_array_table— 58/58 passingtests/decs— 245/245 passing (heaviest user of push/emplace)tests/linq— 1228/1228 passingtests/daslib— 92/92 passingtests/algorithm— 162/162 passingDASLANG_HUGE_HEAP_TESTS=1on a 2.2 GB uint8 array — push/emplace/push_clone at-position (3 tests, 1.3s) + erase + erase-range (2 tests, 0.8s) all PASSdasfmt --verifyclean on full tree (17470 files)mcp__daslang__lintclean ondaslib/builtin.das(was 31 hits → 0)🤖 Generated with Claude Code