Fixed arrays as structural types: Type::tFixedArray replaces TypeDecl dim/dimExpr#3095
Merged
Conversation
Adds the structural fixed-array node and all core TypeDecl support, gated on
baseType==tFixedArray throughout. Nothing produces FA nodes yet (parsers flip
in 1b), so this stage is behavior-neutral: describe/typename text, mangled
names, semantic/lookup hashes and AOT hashes are unchanged for every type
constructible today. dim/dimExpr stay live until the end of Stage 1.
- Type::tFixedArray appended at the END of the enum (AST-only; runtime
TypeInfo stays flattened forever). Registered in das_to_string /
das_to_cppCTypeString / the rtti-side Type enum binding. The C API
das_base_type deliberately does NOT get the value - it describes runtime
TypeInfo, which never carries it.
- TypeDecl fields: fixedDim / fixedDimExpr (one size per node, element in
firstType, dimAuto/dimConst sentinels) + typeMacroExpr (dormant until 1b
moves the typeMacro/typeDecl/tag payload off dimExpr).
- Lifecycle: copy ctor, static clone, gc_collect, visit cover the new fields.
- Identity: isSameType gets a tFixedArray case (fixedDim + element recursion
mirroring the tArray arm) with the canonical-form debug assert - settled:
ref/const/temporary live on the OUTERMOST FA node only. isSameExactType
compares fixedDim.
- Text: describe emits the flattened element-first form ("float[3][4][4]"),
byte-matching the dim-vector output. Mangled name emits by NATURAL
RECURSION (settled): per-node [d] + Y<alias>, element inline - unaliased
chains byte-identical to master; mid-chain aliases shift the Y<> slot to
the level it labels ("[3][4]Y<M4>[4]f"), covered by the planned one-time
version bumps. Mangled-name PARSE flip rides 1b - the [N] text is identical
in both worlds, so the parser must build whichever representation the
program uses. describeCppType reproduces TDim<TDim<...>,N> nesting exactly.
- Size family: getCountOf64 / getStride64 / getBaseSizeOf64 / getAlignOf /
getSizeOf64-failed chain-walking arms preserve the dim-vector meanings.
- Classifier sweep: FA is transparent to classification exactly like the old
dim vector (peel/recurse arms beside every tArray arm). Deliberate calls:
gcFlags recurses WITHOUT gcFlag_heap (inline storage); hasNonTrivialCtor
DOES recurse (FA elements are live at init, unlike empty array<T>);
isCircularType descends FA (no heap indirection to break cycles);
isVecPolicyType guard extended; canDelete peels FA on both self and
pointee; collectAliasing recursion is slightly conservative vs the old
form (extra bare-element append, noted in-source for the 1b review).
- tests-cpp/small/test_fixed_array_typedecl.cpp: hand-built FA nodes proven
against equivalent dim-vector nodes (gc_guard cleanup) - describe/mangled/
cppType text equality, size family incl. float3[4]=48, isSameType matrix,
deep clone of fixedDimExpr, semantic/lookup hash discrimination,
classification parity, and the settled mid-chain-alias mangling golden.
Gate: full local Release build green (incl. utils -exe steps + AOT objects),
tests-cpp-small 50/50 (1.1M assertions, leak-check clean), dastest
10784/10784, test_aot 10123/10123 run exactly as CI does. Note for local
setups: the TypeDecl layout change requires rebuilding external
.shared_module binaries (dasImgui / dasImguiImplot junctions rebuilt here).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eMacroExpr Atomic payload flip (FIXED_ARRAY_REWORK.md, Stage 1b first commit; CI-green standalone — arrays stay on dim vectors until 1b-ii): - parsers: gen2 x6 / gen1 x4 payload writes go to typeMacroExpr (typeMacro name+args, typedecl(expr), $t(expr) tag on its autoinfer firstType) - C++ reads: typeMacroName, describe (tag/typeDecl/typeMacro arms), mangled emit (^<name;hash> — text byte-identical), moreSpecialized typeMacro comparison, inferPartialAliases, inferTypeExpr typeDecl resolution - validator: tracks typeMacroExpr (incl. tag payload on non-payload baseTypes, which the standard visitor never walks) + resolved-FA fixedDimExpr analog - serializer: typeMacroExpr serialized unconditionally after the baseType switch (covers payload nodes AND tag-on-autoinfer); payload arms drop dimExpr; tFixedArray arm added; version 89 -> 90. Note: no in-tree test lane exercises AstSerializer — symmetry of the shared read/write path + version bump is the safety here - das binding (pulled forward from 1f, settled): .dimExpr field becomes a read-only compat property dimExprCompat() — non-empty typeMacroExpr wins, "whatever dimExpr used to hold for this node" — so typemacro_boost, clargs, ast_match, templates_boost keep working unmodified through Stage 1 - remaining dimExpr references classified: array semantics (infer erase/ dimConst resolution -> 1d) or still-live-field infrastructure (visit/clone/ gc/hash/serializer arms — die with the field at end of Stage 1) Gates (all green): full Release build incl. utils -exe + AOT regen; tests-cpp-small 50/50 (1,103,300 asserts); dastest 10784/10784; test_aot 10123/10123 (CI invocation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…verter) is fixed last Per review: the conversion util's vendored gen1 grammar (writes real TypeDecl dim/dimExpr, same 10 site-shapes as the in-tree gen1 parser) ports at the very end of the train, not Stage 5. The dim/dimExpr deletion commit carries only the minimal mechanical compile-flip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The FA parser flip (FIXED_ARRAY_REWORK.md, Stage 1b second commit). Both grammars
and the mangled-name parser now produce structural tFixedArray chains instead of
dim/dimExpr vectors; nothing downstream understands them yet — the world stays
dark until 1c/1d (commit-as-is settled with Boris, class burndown in the plan).
- parser_impl: appendDimExpr becomes the FA-chain builder (3-arg, returns chain
head; const-int shortcut preserved, fixedDimExpr always retained);
attachDimChain wraps the dim chain around the element and hoists the qualifier
flags the old world fused onto the dim-carrying node (const/ref/temporary,
their remove*, implicit/explicitConst/explicitRef/isExplicit/autoToAlias) to
the chain head — alias NEVER hoists; appendAutoDim covers gen1's push-at-end
`[]` arm (wrap-innermost when already FA). The legacy 2-arg appendDimExpr
stays for THE THIRD PARSER (utils/dasFormatter) and dies with the fields.
- ds2/ds parser: dim_list arms build chains, splice arms attachDimChain (the
`$dimlist->dimExpr.clear()` ownership hack disappears), gen1 `{{ }}` table
literal synthesizes FA(dimAuto, autoinfer). Grammar errors kept verbatim.
Old-world quirks reproduce structurally: late-dim front-splice
(`int[3] const [4]` = [4][3]) and gen1 push-at-end (`int[][]` auto innermost).
- mangled-name PARSE case '[' builds an FA node and claims the fullName
remove-suffixes plus an immediately-following Y<name> for THAT node
([3][4]Y<M4>[4]f labels the two-dim node; known cosmetic re-parse asymmetry
for element-side labels, structural identity unaffected).
- tests-cpp/small/test_fixed_array_parser.cpp: parse-shape suites for both
grammars (parse-only via a deliberate trailing parse error — infer cannot
digest FA until 1d), {{ }} makeType shape, and mangled emit<->parse round
trips. Suite also pins a master fact: `int[3][]` is a gen1 syntax error
(dim_list shift preference), so push-at-end only composes via int[]/int[][].
Gates: full Release build green; tests-cpp-small 53/54 (the 1 red compiles
`let arr : int[5]` through infer — recorded 1d burndown). dastest runs ZERO
tests: builtin.das bulk-push signatures with `[]` are FA now, make-array arg
types are still infer-made dim-vectors, and every .das_module initialize meets
the mismatch at to_array_move — daslang.exe cannot boot the in-repo project
until 1d. test_aot not attempted (AOT regen needs a booting daslang).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… flattens Stage 1c of FIXED_ARRAY_REWORK.md: the C++ interop side now produces FA chains. - typeFactory<TDim<TT,size>> and typeFactory<TT[dim]> wrap via the new makeFixedArrayTypeDecl header helper, which hoists the canonical ref/const/temporary trio off the element (mirrors the parser's attachDimChain). isNativeDim moves onto the FA node — its only consumer is aot_cpp.das reading the indexed type's head, unchanged. - SETTLED (discussed): the natural recursion fixes the latent multi-dim order bug — old typeFactory<int[3][4]> produced inner-first dims [4,3] (das int[4][3], row stride 12 instead of 16); believed unexercised in-tree. New shape FA(3, FA(4, int)) is correct by construction and pinned by tests (describe "int[3][4]", stride 16). - makeTypeInfo gains the FA-flatten arm, pulled forward from 1f by necessity: typeFactory feeds handled-struct FIELD types and builtin signatures whose runtime TypeInfo must keep the exact flattened shape — without it a C-array field silently produces dimSize=0 TypeInfo. The arm collects chain dims onto a scratch element clone (head qualifiers ride along); mangled-name cache key unaffected since chain and flattened text are identical. ManagedVector's walk scratch (ast_handle.h) flips to FA(1, clone) and exercises the arm. - makeArgumentType needs no edit — composes via the FA-aware isRefType. Builtin mangled names unchanged (unaliased FA chains byte-identical to the old text); semantic hashes shift, moot while the world is dark. - tests-cpp/small/test_fixed_array_interop.cpp: typeFactory shapes (incl. multi-dim fix + const-hoist canonical form), makeArgumentType composition, and makeTypeInfo flatten parity (dimSize/dim/size/flags/ hash byte-equal vs dim-vector input, shared cache key). Gates: full Release build green; tests-cpp-small 55/56 (the 1 red is the known 1d burndown item — int[5] through infer). World stays dark until 1d. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… flipped Matching core: inferGenericType FA arm (fixedDim match, dimAuto wildcard, firstType recursion; plain auto(TT) binds whole chains via the clone path), applyAutoContracts FA recursion. updateAliasMap untouched by design (auto(TT)[] rides firstType recursion; the dim.clear() root-cause line is now a dead no-op). Alias/verify: inferAlias/inferPartialAliases FA arms with the FA-only label rule (typedef name kept as display label only when the resolved type is an FA chain); per-node dimConst eval in inferTypeExpr; verifyType FA arm. Expression typing: ExprAt/ExprSafeAt FA peel (direct + pointer-to-FA), for-loop source peel, ExprNew chain rewrap around the pointer (dead dim-copy remnants removed), typeinfo is_dim/dim/dim_table_value/is_iterable, finalize_dim gate, ExprAscend FA-of-handle error, ExprWith, each-promotion gate. Make-literals: make-variant/make-struct/make-array convert to the element-walk (mkBaseT) + makeFixedArrayTypeDecl result-wrap pattern; structToTuple walks FA at entry; where-block passT wraps. makeStructWhereBlock wraps too, fixing a latent double-dim append when makeType carried an explicit dim. gen2 fixed_array of an already-dim'd element now wraps OUTER-most (old push_back appended inner-first - same latent order-bug family as the 1c typeFactory fix). Singles: moreSpecialized ranks via fixedDim + FA subtype recursion; allocate_stack ExprNew gate; escape-analysis stack-alloc gate + element walks (persistent flag was missed through the wrapper); tryPromoteConstInt and clone_dim dispatch gates; needAvoidNullPtr sees through FA when allowDim; isLocalOrGlobal ExprAt gate. No-edits proven: dim-GATED classifiers (isStructure/isVariant/isString/ isPointer/isVoid/isWorkhorseType) return false on the FA wrapper exactly as they did on a dim'd node, so baseType-gated call sites keep master behavior for free. Intentional divergence: [[EnumT[2]]] no longer collapses to a single const (master quirk - isEnumT ignored dim). Gates: build green; tests-cpp 55/56 - the known-red int[5] test now passes compile and fails in simulate, i.e. the failure crossed the 1d/1e boundary on schedule. World stays dark until 1e (simulate lowering); 1d+1e push as a train. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ast_simulate.cpp: make-variant/make-struct lowering get element views (the findArgumentIndex/getVariantFieldOffset/structType/annotation reads went through the wrapper; getStride needs NO walk - FA head getStride equals the old dim'd getStride by construction); fakeVariable flatten hack wraps via makeFixedArrayTypeDecl (ref hoists to the head); ExprAscend/ExprNew dispatch walks to the element (persistent flag was silently missed through the wrapper) and ExprNew reads the pointee size via a pointer-node walk; sv_trySimulate_At and both ExprSafeAt branches take range from fixedDim; for-loop fixedSize + the FixedArrayIterator arm flip. ExprDelete untouched: infer routes FA delete to finalize_dim, and the total==1 assert proves a dim'd type never reached it in the old world either. Boot-gate fallout fixed en route: - src/builtin: expect_dim contract and the sort transformCall read fixedDim (innermost node = old dim.back() semantics). - 1a-gap FA arms in ast_typedecl: isAliasOrA2A (isAlias() returned false on FA-of-alias, so ExprCast never resolved `TT -const[N]` - the to_array_move body), applyRefToRef, collectAliasList, isAotAlias. - inferAlias FA arm now applies+clears the head's hoisted remove* contracts, the way the dim'd alias leaf used to. - AST-GC discipline (new failure class, cdb-proven): a fresh node held only in a C++ local across inferFunctionCall gets collected - ExprNew now re-derives the pointer node from the rooted expr->type after the call. Related: gc_local frees ONLY the head while TypeDecl's copy ctor deep-clones children, so a guarded deep clone leaks its subtree - the makeTypeInfo FA-flatten arm now uses a shallow borrow scratch, and the ManagedVector walk scratch guards its element node (master parity). - daslib/ast_boost: walk_and_convert_array/table built dim-vector types via the das-side .dim push (made my make-array infer double-wrap); they now wrap via the new public make_fixed_array_type helper (canonical qualifier hoist), walk_and_convert dispatches on tFixedArray, and fixedDim / fixedDimExpr are exposed on the das-side TypeDecl (1f slice pulled forward by necessity - dastest -> clargs -> $v hits this path at boot). Gates (train tip): tests-cpp 56/56 - the int[5] known-red flipped; daslang boots and runs fixed arrays end-to-end; tests/fixed_array characterization 86/86; zero GC leaks; full-tree dastest 10632 tests, 10621 passed, 11 file-level compile errors = the 1f burndown (dasPUGIXML/test_serial_dim, decs/dim_test, json/types, language/invalid_types, match x2, stbimage x4, typemacro/test_basic). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mpat
Stage 1f of FIXED_ARRAY_REWORK.md. The 11-file burndown collapsed into
four classes:
1) Generic alias dim semantics = MASTER-COMPAT PEEL (settled). Master's
rule, pinned empirically against a saved pre-flip build: a generic
alias use-site's own dims REPLACE the bound type's dims - bare TT
bound from int[3] is the ELEMENT int; TT[4] is int[4]; the strip
applies even through array<auto(TT)>. Module typedefs append
naturally (both worlds already agreed). peelFixedArrayAliasBinding
at the alias leaf of inferAlias + inferPartialAliases (head
qualifiers transfer to the element; the partial-alias arm keeps the
binding's label). The FA recursion arm now HOISTS the resolved
element's ref/const/temporary to the chain head (canonical form) -
without it TT[4] kept const on the element and var-decl
const-stripping missed it. daslib's `TT[typeinfo dim(x)]`
reconstruct pattern (json_boost/PUGIXML_boost/decs) works unmodified.
2) das-side `.dim` is now a READ-ONLY flattened compat property
(TypeDecl::dimCompat -> per-node transient dimCompatCache; NOT the
legacy dim field - warming that would nondeterministically revive
dead C++ dim-vector loops on FA nodes). 59 daslib read sites ride it
unmodified. das writers break at compile by design; in-tree writers
ported here: match.das (pop -> firstType), typemacro test fixture +
tutorial twin (-> make_fixed_array_type), dasGlsl produce_zero,
dasLLVM llvm_jit x7 (clear/erase/shift-resize -> element walks; the
`new Handle[N]` tHandle gate now walks the chain;
LLVM_JIT_CODEGEN_VERSION 0x22 -> 0x23).
3) aot_cpp.das had four FA gaps (the 1d+1e train's AOT lane was red
from these): describeCppTypeEx panicked on FA nodes ("Missed type
tFixedArray") and emission swallows macro panics, so struct fields
and local declarations silently vanished from generated C++; dim'd
make-variant dropped its das_get_variant_field::set wrapper; dim'd
make-struct tHandle gate + tuple/variant field helpers, same class;
dim'd ExprNew emitted the POINTER type where das_new_dim<> wants the
POINTEE (TDim<T**> conversion error) and mis-branched handle news
past das_new_dim_handle. All fixed via the fa_element clone-walk
helper (clone-walk keeps the result non-const whatever flavor the
caller holds); dims still emit from the head's .dim view.
4) verifyType's FA too-big check now multiplies element COUNTS across
the chain (master parity: 32767^2 passes infer; lint owns byte-size
with the site-specific exceeds_* codes). decs get_ro declared its
dim'd return as TT[typeinfo sizeof(value)] - bytes - and worked on
master only because an unresolvable result dim was silently
discarded; fixed to typeinfo dim(value).
Known gap (deliberate): -[] (removeDim) on FA-typed generic params
still erases the legacy vector only - zero in-tree users; revisit at
Stage 4/5.
Gates: alias probes match master 100%; all 11 burndown files green;
tests-cpp 56/56; tests/fixed_array 86/86; full tree 10784/10784
interpreted and 10123/10123 under test_aot -use-aot; zero GC leaks in
both modes; lint 0 errors on every changed file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…weep Pre-push lint on the 1f-touched files surfaced two pre-existing issues: - STYLE030 false-flagged `require daslib/functional` in decs.das as unused: repeat_ref is called only inside an UNINSTANCED generic body, where calls stay unresolved (func==null) and leave no used_modules trace - dropping the require breaks instantiation in every decs dim test. STYLE030 now collects unresolved generic-body call names (qualification stripped) and treats a require as used when it exports a function or generic matching one of them. Genuinely-unused requires still flag (probed). - modules/dasGlsl/glsl_internal.das: 148 pre-existing STYLE028 hits (self-> receivers on class method calls); mechanical sweep, since touching the file for the .dim writer port put it under the hook's changed-file lint. Gates: lint 0 issues on all touched files; full tree 10784/10784, zero GC leaks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Revises the alias decision in the previous commit, per review: auto(TT) matched against int[4] binds TT = int[4]; TT[2] is int[2][4] (an array of 2 TT, natural nesting); array<auto(TT)> against array<int[3]> binds TT = int[3] - inexpressible on master; def two(a : auto(TT); b : TT) accepts (int[3], int[3]). The flattened world's strip/replace rule (bare TT was the ELEMENT; use-site dims REPLACED the bound ones) is deliberately dead - it made generics clumsy and unsupportable, and existed only because a single node carried both element and dims. The master-compat peel is reverted. The invariant that keeps most of daslib unchanged: auto(TT)[] - the explicit [] suffix - still binds TT to the ELEMENT (the [] eats one dim level during matching), so the builtin clone/to_array/table-[] families and decs get_ro's TT[typeinfo dim(value)] reconstruct remain correct as written. Ported the bare-auto(TT) dim arms to the new binding: json_boost from_JV and PUGIXML_boost from_XML (`var ret : TT -const -&` - TT IS the array type), and seven decs functions (decs_array / get / get_default_ro / get_component / ComponentMap get / make_callbacks / make_component) where every `static_if (typeinfo is_dim(...))` arm collapsed into its else arm - decs.das alone nets -160 lines, which is the supportability win this flip buys. External code using the TT[typeinfo dim(x)] reconstruct on bare auto(TT) params breaks loudly at compile; bodies using bare TT as the element type change meaning silently - test suites are the net. Gates: probe matrix = natural binding everywhere; tests-cpp 56/56; tests/fixed_array 86/86; json/PUGIXML/decs green; full tree 10784/10784 interpreted + 10123/10123 under test_aot -use-aot; zero GC leaks in both modes; lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hive recursion; default<T[N]> Stage 4's builtin.das half, pulled forward per review: natural alias binding makes the base generics cover every dedicated container-FA overload with identical bodies. Deleted 22 defs (array<T[N]> push x2/emplace/push_clone x2; table<K;V[N]> get x4/get_value/insert x2/insert_clone x2/emplace/values x2/ get_key/clone x2; one-arg clone x2). Capability gains: push_clone of clone-only rows (old gate was can_copy; the const-src body was un-instantiable rot), at-index push of FA rows, size mismatch is now a type error. archive.das: 6 stacked [][]..[] serialize overloads -> ONE natural recursion (auto(TT)[] peels a level per call); bulk-memcpy gate is_raw && (is_workhorse || is_dim) keeps exact wire parity; >6-D now works. default<T[N]> fixed (broken-but-unreachable on master): 0-element FA make-struct now zero-inits the whole declared shape - infer tolerates 0 provided elements, simulate zero-fills getSizeOf() instead of one element's stride. Target spec enabled: _target_inference.das -> test_target_inference.das incl. the get_key subtest (Stage 4 gate). Settled decoration: auto(TT) <- int[4] binds "int const[4]"; auto(TT)[] <- float[4][4] binds "float[4]" (the [] ate the qualifier-bearing chain head). style_lint STYLE030: unresolved generic-body call names now match against the require's PUBLIC RE-EXPORT CLOSURE too (daslib/rtti re-exporting builtin rtti - archive.das serializes function<> by mangled-name hash in a generic body). Gates: fixed_array 95/95, full tree 10793/10793 interpreted, 10132/10132 under test_aot -use-aot (two-pass build), lint 0 issues, formatter clean. Net -313 LOC. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fix #3077 native-dim field pun Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… auto, master parity) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tion-pass fix; JIT codegen version 0x24 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s deleted; stdlib generics pinned multi-dim Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…posed+renamed; -[] peel; rst/glsl FA render fixes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… makeTypeInfo chain-native; dasFormatter grammar flip; serialization v91 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tural generic binding + one-level -[] peel in generic_programming.rst Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s (post-rebase) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR completes the fixed-array type rework by replacing TypeDecl’s flattened dim/dimExpr qualifiers with a structural Type::tFixedArray node, so fixed arrays participate in the same recursive type machinery as other container types and preserve array-ness through generic binding, typedefs, and codegen/tooling.
Changes:
- Introduces structural fixed-array representation (
Type::tFixedArray) across parser, AST, inference, simulation, RTTI/serialization, and AOT/JIT tooling. - Migrates type-macro payload storage from
TypeDecl.dimExprtoTypeDecl.typeMacroExpr, updating grammars, serialization, and macro helpers. - Updates/extends test coverage (das + C++) for parsing, text/mangling, interop, inference semantics, and stdlib generic behavior over multi-dim/aliased fixed arrays.
Reviewed changes
Copilot reviewed 76 out of 76 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/fix-lint-errors/main.das | Updates fixer logic to detect fixed arrays via Type.tFixedArray. |
| utils/dasFormatter/ds_parser.ypp | Updates formatter grammar actions to build tFixedArray chains and use typeMacroExpr. |
| utils/dasFormatter/ds_parser.cpp | Regenerates formatter parser output reflecting the grammar changes. |
| tutorials/macros/type_macro_mod.das | Ports tutorial typemacro example from dimExpr to typeMacroExpr and uses fixed-array constructors. |
| tests/typemacro/test_basic.das | Updates typemacro tests/docs to reference typeMacroExpr. |
| tests/typemacro/_typemacro_mod.das | Updates raw typemacro module to consume typeMacroExpr and construct fixed arrays structurally. |
| tests/fixed_array/test_target_inference.das | Enables/updates acceptance tests for new generic binding and -[] semantics. |
| tests/fixed_array/test_stdlib_generics.das | Adds coverage for stdlib generics operating over multi-dim/typedef’d fixed arrays. |
| tests/fixed_array/test_interop.das | Makes interop test AOT-included and expands coverage for native C-array field surfaces. |
| tests/aot/CMakeLists.txt | Re-includes fixed-array interop test into the AOT glob. |
| tests-cpp/small/test_fixed_array_typedecl.cpp | Adds C++ tests for tFixedArray text/mangle/size/identity/hash/classification. |
| tests-cpp/small/test_fixed_array_parser.cpp | Adds C++ parse-shape tests for both grammars and mangled-name round-trips. |
| tests-cpp/small/test_fixed_array_interop.cpp | Adds C++ tests for typeFactory fixed-array chains and flattened TypeInfo. |
| src/simulate/debug_info.cpp | Adds human-readable name for Type::tFixedArray. |
| src/parser/parser_impl.h | Replaces old dim helpers with appendDimExpr/attachDimChain/appendAutoDim for FA chains. |
| src/parser/parser_impl.cpp | Implements FA-node construction and chain attach/auto-dim behavior (incl gen1 quirks). |
| src/parser/ds2_parser.ypp | Updates gen2 parser to build FA chains and use typeMacroExpr. |
| src/parser/ds2_parser.cpp | Regenerated gen2 parser output. |
| src/parser/ds_parser.ypp | Updates gen1 parser to build FA chains and use typeMacroExpr. |
| src/parser/ds_parser.cpp | Regenerated gen1 parser output. |
| src/builtin/module_builtin_runtime.cpp | Updates expect_dim compatibility check to use tFixedArray. |
| src/builtin/module_builtin_runtime_sort.cpp | Updates sort call rewrite to treat fixed arrays structurally (outermost dimension). |
| src/builtin/module_builtin_rtti.h | Exposes Type::tFixedArray via builtin RTTI enum binding. |
| src/builtin/module_builtin_ast_serialize.cpp | Updates AST TypeDecl serialization for FA nodes + moves typemacro payload to typeMacroExpr; bumps version. |
| src/builtin/module_builtin_ast_annotations_1.cpp | Exposes new TypeDecl fields (fixedDim, fixedDimExpr, typeMacroExpr) to scripts. |
| src/ast/ast.cpp | Updates “local/global” checks to treat fixed arrays via tFixedArray. |
| src/ast/ast_validate.cpp | Ensures validation/GC-root tracking walks typeMacroExpr and fixedDimExpr. |
| src/ast/ast_simulate.cpp | Updates simulation paths that need “element view” when makeType is a fixed-array chain. |
| src/ast/ast_program.cpp | Adjusts constant creation logic post-dim removal. |
| src/ast/ast_lint.cpp | Updates null/annotation pointer heuristics to treat fixed arrays as “dim’d”. |
| src/ast/ast_infer_type_op.cpp | Updates inference ops to detect fixed arrays via tFixedArray. |
| src/ast/ast_infer_type_helper.cpp | Adds FA verification + updates alias inference to preserve fixed-array structure and new -[] behavior. |
| src/ast/ast_infer_type_function.cpp | Updates overload specialization comparisons for FA vs non-FA and typemacro arg storage. |
| src/ast/ast_generate.cpp | Updates generated helper types to wrap counts via FA nodes instead of dim-vectors. |
| src/ast/ast_escape_analysis.cpp | Updates stack allocation heuristics and type unwrap logic for FA chains. |
| src/ast/ast_debug_info_helper.cpp | Flattens FA chains into runtime TypeInfo.dim[] while keeping element metadata correct. |
| src/ast/ast_allocate_stack.cpp | Updates new[] stack-top sizing detection for FA nodes. |
| modules/dasSQLITE/src/dasSQLITE.main.cpp | Updates uint8-pointer-to-string fixup logic to no longer depend on dim-vectors. |
| modules/dasSQLITE/daslib/sqlite_linq.das | Updates scalar renderability gating for FA via Type.tFixedArray. |
| modules/dasSQLITE/daslib/sqlite_boost.das | Ports typemacro payload access to typeMacroExpr and applies minor cleanups. |
| modules/dasPUGIXML/daslib/PUGIXML_boost.das | Updates fixed-array generic binding usage to new “TT is the whole array” semantics. |
| modules/dasLLVM/daslib/llvm_jit.das | Updates LLVM JIT codegen/interop for FA nodes and element-type extraction. |
| modules/dasLLVM/daslib/llvm_jit_run.das | Bumps JIT codegen cache version. |
| modules/dasLLVM/daslib/llvm_jit_common.das | Reworks LLVM type construction to recurse through FA nodes. |
| modules/dasLLVM/daslib/llvm_exe.das | Updates extern collection logic for new T[N] where head is tFixedArray. |
| include/daScript/simulate/debug_info.h | Adds tFixedArray to runtime debug Type enum (documenting AST-only nature). |
| include/daScript/ast/ast_typedecl.h | Adds fixedDim/fixedDimExpr/typeMacroExpr, introduces makeFixedArrayTypeDecl, updates classifier helpers. |
| include/daScript/ast/ast_infer_type.h | Extends alias lookup APIs to propagate constUnderDim. |
| include/daScript/ast/ast_handle.h | Fixes makeTypeInfo scratch construction for FA head + element lifetime under GC guards. |
| examples/flatten/backend/shader_dsl_boost.das | Updates shader DSL validation to reject fixed arrays via Type.tFixedArray. |
| doc/source/reference/language/generic_programming.rst | Documents new fixed-array generic binding + one-level -[] behavior. |
| doc/source/reference/language/arrays.rst | Documents multi-dim fixed arrays, alias composition, iteration semantics, and typeinfo dim. |
| daslib/typemacro_boost.das | Ports typemacro helper to typeMacroExpr and FA detection. |
| daslib/templates_boost.das | Ports tag payload access to typeMacroExpr. |
| daslib/style_lint.das | Updates array/dim checks and adds unresolved-call tracking to reduce false “unused require” flags. |
| daslib/sort_boost.das | Updates qsort macro to route fixed arrays via FA detection. |
| daslib/rst.das | Updates type description printing to emit FA chains structurally. |
| daslib/perf_lint.das | Updates perf lint array detection logic to include Type.tFixedArray. |
| daslib/match.das | Updates pattern matching helpers to treat fixed arrays structurally (fixedDim + element recursion). |
| daslib/json_boost.das | Updates fixed-array decode path for new generic binding semantics (TT is full FA). |
| daslib/is_local.das | Updates local/scope helpers to treat fixed arrays via Type.tFixedArray. |
| daslib/decs_boost.das | Updates comments/logic references from dim-vectors to FA nodes. |
| daslib/contracts.das | Updates contract checks to treat fixed arrays as array-like via Type.tFixedArray. |
| daslib/clargs.das | Ports Option typemacro payload access to typeMacroExpr. |
| daslib/builtin.das | Removes redundant fixed-array overload stacks now covered by natural binding. |
| daslib/ast_match.das | Ports tag payload access and updates dim-field matching for FA nodes. |
| daslib/ast_boost.das | Adds make_fixed_array_type helper and updates conversion logic to build FA nodes. |
| daslib/archive.das | Generalizes fixed-array serialization to arbitrary depth via structural recursion. |
| daslib/apply.das | Drops obsolete dim-vector assertions for apply macros. |
| daslib/aot_cpp.das | Updates AOT C++ type description and fixes native C-array field access punning to TDim view. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
das2rst validates handmade docs positionally against reflection: - enumeration-rtti-Type.rst: add line for the new tFixedArray value - structure_annotation-ast-TypeDecl.rst: dim/dimExpr lines replaced by fixedDim/fixedDimExpr/typeMacroExpr; firstType line mentions the fixed-array element - new handmade doc for ast_boost::make_fixed_array_type (das2rst generated a // stub, which the docs workflow rejects) Verified locally: das2rst clean, no stubs, no untracked generated files (generated/ is gitignored), sphinx-build -W html succeeds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- makeConst: restore the fixed-array early-return dropped in stage 6 (Copilot review; unreachable today but master returned nullptr gracefully, and the structural-world spelling of the old dim guard is the baseType check) - expect_dim: compatibility error message says "fixed size array" instead of the legacy "dim []" terminology (Copilot review) - tests-cpp: wrap bit-field operands in bool() inside CHECK macros. doctest's expression decomposition binds operands by reference, which C++ forbids for bit-fields; MSVC tolerated it, every clang/gcc CI lane failed to compile. Noted in skills/writing_cpp_tests.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
In the flattened world, plain auto(T) binding did not carry dims, so safe_addr(arr) where arr : bool[4] bound T=bool and produced bool?# — an element pointer that matched C-interop params like `bool? const implicit` (glGetBooleanv et al). The structural world binds T to the whole array, producing bool[4]?#, which correctly no longer matches — breaking dasOpenGL in extended_checks (the module is GLFW-gated, so local suites never compile it). Restore the rail where it belongs: safe_addr(x : auto(T)[]&) : T -&?# returns a temporary pointer to the FIRST ELEMENT, mirroring C array decay. Multi-dim peels one level (int[2][3] -> int[3]?#), exactly like C's T[2][3] -> T(*)[3]. Overload resolution prefers the [] form for fixed arrays and keeps the base form for everything else; call sites (opengl_state.das and downstream repos) need no edits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Uncategorized-section grep in doc.yml rejects any public function not assigned to a group_by_regex in das2rst.das — a separate gate from the das2rst run itself, which passes locally without it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| let was_in_txn = db |> in_transaction() | ||
| db |> exec(txn_begin_sql(was_in_txn, mode)) | ||
| var success = false | ||
| var success : bool |
Comment on lines
2709
to
2711
| uint32_t AstSerializer::getVersion () { | ||
| static constexpr uint32_t currentVersion = 89; | ||
| static constexpr uint32_t currentVersion = 91; // 91: TypeDecl dim/dimExpr fields deleted (FIXED_ARRAY_REWORK.md, stage 6) | ||
| return currentVersion; |
This was referenced Jun 11, 2026
borisbat
added a commit
to profelis/daScript-plugin
that referenced
this pull request
Jun 11, 2026
daslang 0.6.3 (GaijinEntertainment/daScript#3095) replaces TypeDecl's flattened dim vector with structural Type::tFixedArray chains (element in firstType, one size per node in fixedDim). New server/0.6.3 scripts walk the chain in parse_typedecl; the client model stays flat (leaf baseType + dim list + tdk1 = one-level peel), so completion.ts is untouched. Registered in VERSION_SCRIPT_DIRS; 0.6.1/0.6.2 binaries keep the 0.6.1 scripts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
profelis
pushed a commit
to profelis/daScript-plugin
that referenced
this pull request
Jun 11, 2026
daslang 0.6.3 (GaijinEntertainment/daScript#3095) replaces TypeDecl's flattened dim vector with structural Type::tFixedArray chains (element in firstType, one size per node in fixedDim). New server/0.6.3 scripts walk the chain in parse_typedecl; the client model stays flat (leaf baseType + dim list + tdk1 = one-level peel), so completion.ts is untouched. Registered in VERSION_SCRIPT_DIRS; 0.6.1/0.6.2 binaries keep the 0.6.1 scripts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jun 11, 2026
pull Bot
pushed a commit
to forksnd/daScript
that referenced
this pull request
Jun 11, 2026
…UDE.md/skills Plan lives in COVERAGE_GAP.md (stages 0-4; evidence base = the PR GaijinEntertainment#3095 babysitting session, where every CI failure was a local-vs-CI oracle mismatch). Stage 0 (this PR): - CLAUDE.md: syntax/factual corrections are now fix-in-place ALWAYS (verified against ds2_parser.ypp + probe-compile); propose-first narrowed to restructuring/removals/new skills. - CLAUDE.md: new "Fixed arrays (structural since 0.6.3)" section — chain model, one-peel rule, generic binding (whole-bind vs []-peel, one-level -[]), safe_addr element decay, TypeInfo-stays-flattened, the both-worlds isArray() note for externals. - skills/das_macros.md: macro-author view — fixedDim sentinels, qualifiers on the chain head, make_fixed_array_type, typemacro payloads in typeMacroExpr (dimExpr is gone), leaf-walk recipe. - skills/linq.das examples: typeDecl.dim (deleted field) -> argTypes. - Gen2 currency review: every syntax claim in CLAUDE.md's gen2 section + das_formatting/regex/strings/daslib_modules skills verified against the grammar; suspicious ones probe-compiled (all held up). Four shipped-but-undocumented features added: function/method arrow bodies (def f(...) : T => expr), call-site block arrow shorthand ($(a, b) => a < b), piped default-argument padding. Co-Authored-By: Claude Fable 5 <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.
Replaces the flattened
dim/dimExprqualifier vectors onTypeDeclwith a structuralType::tFixedArraynode, so fixed arrays resolve through the same recursivefirstTypemachinery as every other container. Full plan, settled design decisions, and per-stage implementation notes live in-repo inFIXED_ARRAY_REWORK.md(every stage was review-gated on the branch).Why
On master,
dimsat in the qualifier set next toconstant/ref, with verified consequences:auto(TT)←int[4]boundTT = int— array-ness silently strippedauto(TT)[]←float[4][4]— no match (exact dim-count required)var a : M4[3](M4 =float[4][4]) flattened tofloat[3][4][4]— typedef identity destroyedtable<K;V[N]>/array<T[N]>families) reconstructing the thrown-away type, each covering only one[]levelWhat changes for users
auto(TT)binds the whole array (TT = int[4]);auto(TT)[]peels one level (TT = float[4]fromfloat[4][4]) and inherits parameter constness (non-varbinds const,varbinds mutable);TT - []removes one level (was: all levels);default<TT>is a zeroed fixed array.M4[3]stays 3 × M4;a[0]is an M4.auto[]overloads (previously fell through to plainauto).default<T[N]>fixed (was broken-unreachable);get_key(table<K;V[N]>)fixed; sort-with-comparator over rows fixed (the transform routed rows to the workhorse-only path); no-comparator multi-dim sort is now a clean error instead of a silent flat-sort; >6-D archive serialization works (was a 6-deep overload stack).arrays.rst; binding rules + one-level-[]ingeneric_programming.rst.Invariants kept
TypeInfostays flattened forever (it describes layout).isX()predicate drops itsdim.size()branch.Compatibility notes
LLVM_JIT_CODEGEN_VERSION→ 0x24..shared_moduleDLLs built before this change crash daslang at startup (the dyn-module descriptor scan dlopens them; TypeDecl layout changed). Rebuild external module stacks after pulling.arg->type->dim.size()==0guards port to!arg->type->isFixedArray()(dasImgui/nodeEditor/implot edits staged locally, pushed after this merges).Gates (local, Windows/MSVC; this PR is the branch's first full-matrix CI)
interp 10920/10920 · AOT 10240/10240 (two-pass, content-stable regen) · JIT 10475/10475 · tests-cpp 56/56 (1.1M assertions) · dasSQLITE 904/904 · lint 34 changed .das files clean · Sphinx clean · zero GC leaks all lanes.
Closes #3077 (AOT emitter native-dim field fix is Stage 2 of this train).
Related: #3090 (LINT003 follow-up, filed during the rework), #3094 (pre-existing das-fmt converter self-test failures, proven not rework-caused via 3-way baseline).
🤖 Generated with Claude Code