phase 8b: typeinfo is_int / is_int64 + int|int64 disjunction spike#2764
Merged
Merged
Conversation
Spike for the next big chunk of the 64-bit array/table widening project (PR-D, linq surface). Question: can a function accept `int | int64` as a single signature and fork inside the body with static_if, so the ~10 linq functions targeted by PR-D widen with one signature each instead of doubled overloads? Answer: yes -- `def take_or(x : int | int64)` already parses (the disjunction-parameter shape was used in tests/language/option_type.das for ref/auto resolution). What was missing was a clean dispatch predicate; `stripped_typename(x) == "int"` is a string-compare hack for something this prominent. Adds two `typeinfo` traits in src/ast/ast_infer_type.cpp next to `is_numeric`, following the `is_string` pattern (baseType match + `dim.size() == 0`): typeinfo is_int(x) -> baseType == tInt && dim.size() == 0 typeinfo is_int64(x) -> baseType == tInt64 && dim.size() == 0 tests/long_array_table/test_int_int64_disjunction.das pins both halves (disjunction-parameter dispatch + the two new traits) with static_assert type-contract probes so silent reverts on either side flip the test red. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds targeted typeinfo traits for discriminating int vs int64 at compile time, enabling int | int64 disjunction parameters to be handled with a single signature and static_if dispatch (supporting upcoming 64-bit linq surface widening work).
Changes:
- Added
typeinfo is_int(...)andtypeinfo is_int64(...)traits in the compiler’s typeinfo trait folding. - Added a new regression test covering
int | int64parameter dispatch and a static-assert “contract” matrix for the traits.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/long_array_table/test_int_int64_disjunction.das | New tests validating disjunction parameter branching via typeinfo is_int / is_int64. |
| src/ast/ast_infer_type.cpp | Implements constant-folding support for new typeinfo traits is_int and is_int64. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9 tasks
pull Bot
pushed a commit
to forksnd/daScript
that referenced
this pull request
May 21, 2026
First commit on the longarr phase 8c branch. Widens the decs storage
type-level surface to int64 and rewrites the FixedArrayIterator C++
runtime to int64 sizes. This is preparation -- the actual >INT_MAX
runtime scenario is gated by the entityLookup resize cascade
(decsState.entityLookup |> resize(int(id_base) + count) caps total
entities at INT_MAX globally) and EntityId.id : uint. Both follow in
subsequent commits on this same branch before the PR opens.
Changes:
daslib/decs.das
Archetype.size : int -> int64 (the audit's silent-corruption site)
entityLookup tuple .index : int -> int64
get_eid(... index : int) -> int64
remove_entity(... di : int) -> int64
decs_array(... capacity : int) -> int64 (routes through _i64 builder)
entity_count() : int keeps int return + panics if total > INT_MAX
(mirrors length() / long_length() surface contract)
long_entity_count() : int64 NEW -- int64-safe accessor
for_eid_archetype invoke(blk, ..., int(lookup.index)) cast at boundary
create_entities_from_cmp invoke(fill_blk, ..., int(eidx), ...) cast at boundary
get_default_ro / get_optional cap at INT_MAX with panic guard before
passing to repeat/repeat_ref (functional.das int64
widening is a separate followup)
Stride multiplications (eidx * c.stride, arch.size * c.stride, etc.)
pick up int64(c.stride) casts at every site
Comparisons with literal 0 widened to 0_l
range(arch.size) -> range64(0_l, arch.size)
daslib/decs_state.das
EcsArchetypeView.size : int -> int64
Switched _builtin_make_temp_array -> _i64 variant for the dump path
daslib/builtin.das
each(a : auto(TT)[]) passes int64(typeinfo dim(a)) to the widened
iterator binding -- the only other in-tree caller of
_builtin_make_fixed_array_iterator besides decs.das.
C++ runtime (the "rewrite said iterator to use 64 bit" piece):
include/daScript/simulate/runtime_array.h
FixedArrayIterator::size : uint32_t -> uint64_t
SimNode_FixedArrayIterator::size : uint32_t -> uint64_t
include/daScript/simulate/aot_builtin.h
builtin_make_fixed_array_iterator(... int size, ...) -> int64_t size
src/builtin/module_builtin_runtime.cpp
Same widening in the impl; negative size clamps to empty (same
pattern as builtin_make_temp_array_i64).
Tests
tests/decs/test_archetype.das
Five comparison literals widened to *_l (existing tests, same logic).
tests/decs/test_archetype_size_type.das NEW
static_assert type-contract probes locking Archetype.size : int64,
long_entity_count() : int64, entity_count() : int. Uses
stripped_typename so the test doesn't depend on PR GaijinEntertainment#2764 (typeinfo
is_int64) landing first.
tests/decs/test_archetype_bulk_create_int64.das NEW
Small-N (100K + 1K) runtime regression covering bulk-create + delete
arithmetic neighbors. The genuine >INT_MAX memory-gated probe waits
for the cascade widening to enable past-INT_MAX creation.
Test status: tests/decs/ 244/244 pass. tests/language/ 1003/1003 pass.
tests/long_array_table/ 45/45 pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pull Bot
pushed a commit
to forksnd/daScript
that referenced
this pull request
May 21, 2026
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 GaijinEntertainment#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>
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
Spike for the next big chunk of the 64-bit array/table widening project (PR-D, linq surface widening). The question this PR answers: can a function accept
int | int64as a single parameter signature and fork inside the body viastatic_if, so the ~10 linq functions targeted by PR-D widen with one signature each instead of doubled overloads?Yes.
def take_or(x : int | int64)already parses — the disjunction-parameter shape is used in tests/language/option_type.das for ref/auto resolution. What was missing was a clean dispatch predicate inside the body;stripped_typename(x) == "int"is a string-compare hack for something this prominent.What changed
Two new
typeinfotraits in src/ast/ast_infer_type.cpp, placed right afteris_numericand following theis_stringpattern (baseTypematch +dim.size() == 0):typeinfo is_int(x) -> baseType == tInt && dim.size() == 0 typeinfo is_int64(x) -> baseType == tInt64 && dim.size() == 0Scope is intentionally surgical —
is_int+is_int64only, matching PR-D's immediate need. Sibling traits (is_uint,is_int8/16/32, etc.) can be added later when a real call site needs them.Test plan
test_int_branch/test_int64_branch—def take_or(x : int | int64)withstatic_if (typeinfo is_int(x))dispatch returns the right value for both call shapestest_typeinfo_is_int_traits—static_assertmatrix locksis_int/is_int64against silent reverts (true for the matching type, false for the other and foruint)tests/long_array_table/full dir: 48/48 passtests/apply/,tests/language/: no regressions from the trait addition--verify+ lint passUnblocks
PR-D (linq surface widening — take/skip/element_at/chunk/last/single/...) can now use one
int | int64signature per function withstatic_if (typeinfo is_int(x))inside the body, instead of doubling overloads.🤖 Generated with Claude Code