[pull] master from GaijinEntertainment:master#1028
Merged
Conversation
) Two independent bugs surfaced together by the linter's `no_infer_time_folding=true` + `no_optimizations=true` policy combo. 1. Compiler: `concept_assert` / `static_assert` cond never gets folded. `typeinfo sizeof(T) <= typeinfo sizeof(U)` rewrites to `ExprConstInt <= ExprConstInt` at infer time, but `InferTypes::visit(ExprOp1/Op2/Op3)` only folds when `enableInferTimeFolding` is on. With lint disabling it and `no_optimizations` skipping `ConstFolding`, the binop stayed unfolded and `ContractFolding::visit(ExprStaticAssert*)` raised the spurious 30151. Mirror the existing static_if save+force-enable+ restore pattern in `preVisit`/`visit(ExprStaticAssert*)` so the cond subtree always folds. 2. Daslib: 6 sites used `if (typeinfo X)` instead of `static_if`. These relied on the same infer-time folding to elide the dead branch (whose body references fields/operations only valid in the true branch's universe). Under lint flags, both branches survive and the dead one fails to resolve. Convert all to `static_if`: `decs_boost.das:244` (`a._aka`), `builtin.das:403/892/914/1183`, `json_boost.das:477`. `extended_checks` gates the lint step to `matrix.target == 'linux'`, so this surfaced as "linux x64 only" in CI; verified platform-independent locally on Windows daslang.exe. Also: 2 pre-existing STYLE028 hits in `decs_boost.das` (`self->implement` -> `implement`), required by the "every changed .das file lint-clean" PR rule once the PR touches that file. Regression fixture: `tests/_issue_2830_lint_repro.das`. CI lint runs over changed .das files; the fixture exercises the failing path on this PR and continues to exercise it on any future PR that touches it. Verified locally on WSL Ubuntu2404-CI (clang 18.1.3, Release): - lint clean on all 4 repro variants - tests/decs 245/245 pass - tests/json 266/266 pass - tests/lint 8/8 + utils/lint/tests 38/38 pass Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lint-static-assert-cond-fold ast,daslib: fix spurious 30151 on concept_assert under lint flags (#2830)
Two slices closing the final m4-vs-m3f gaps from #2824's residual outliers. Slice 1 — trivial-let elision (closes sum_aggregate_m4 1.3ns gap): When `_select(_.userName)` peels to a single `decs_tup.<field>` reference, rename the chain bind directly to the iter var instead of synthesizing `decs_sel_N`. wrap_decs_chain skips emitting the `let decs_sel_N = car_price` binding entirely; the action's `acc += <iterVar>` references the iter var natively. Required extending DecsTupUsageScanner with an iter-var-→-user-name reverse map so bare iter-var refs still seed the pruner (previously: empty usedNames fell through to unpruned-default, defeating the elision). Slice 2 — reverse_take skip-into-tail (closes reverse_take_m4 5.2× gap): For `from_decs(...).reverse().take(N).to_array()` with no where/select, emit a two-pass invoke: pass 1 sums `arch.size` (no entity load), pass 2 uses for_each_archetype_find to skip whole archetypes whose cumulative size still fits below the skip threshold, then a per-iter skip-counter through the partial archetype, push into a takeN-sized buffer, and `return true` to stop iteration once buf is full. reverse_inplace runs on the small N buffer at end, not the full source. where/select fall through to the legacy buffer+reverse_inplace+resize emit unchanged. Bench (INTERP, 100K rows, ns/op): - sum_aggregate_m4 3.4 → 2.1 matches m3f (was the systemic 1.3ns gap) - reverse_take_m4 48.0 → 9.2 5.2× win, allocs 42B → 1B - select_where_sum_m4 7.5 → 7.5 matches m3f (elision benefits this too) - contains_match_m4 2.1 → 1.4 beats m3f at 2.2 - chained_where_m4 6.6 → 6.6 no regression - count_aggregate_m4 4.1 → 4.1 no regression Tests: - New splice-shape assertions: trivial-let elision (no decs_sel binding for `_select(_.val).sum()` and `_where(_)._select(_.val).sum()`) - New splice-shape for skip-into-tail (for_each_archetype_find count==1, decs_skips local presence) - New parity tests: multi-archetype reverse+take, take(N>total), empty source — covers the whole-archetype-skip + partial-archetype + early-return arms 1388/1388 linq + 245/245 decs + 782/782 dasSQLITE green INTERP. MCP + CI lint clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
#2835 fixed the typer-pass-order #2830 that originally tripped this test on the extended_checks (linux, 64) lane. With master now containing the fix, the test compiles cleanly on all lanes. Re-adding it covers a case the current suite missed: from_decs_template(type<Row>)._where(_.a >= 0)._where(_.b >= 0).count() Three chained single-field _where_s — all 3 fields read via field access, no whole-var ref. The splice must keep all 3 get_ros (no slot pruning) but elide the named-tuple bind (no decs_tup in the body, iter vars read directly). Lesson saved to memory: not every CI lane runs every test, so "platform-specific" failures often mean "we only check this on one platform" — not that the bug itself is platform-specific. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The original test created one A-only and one B-only archetype, but the query `from_decs_template(type<RevTakeMultiArchA>)` only matches A — the B archetype never enters for_each_archetype, so the cross- archetype skipping arm wasn't actually exercised. Now creates two MATCHING archetypes: both have `rev2_id` (so both satisfy the query), but the second group also has the rev2_b_* extras which lands it in a separate archetype class. With A1=4 + A2=5 → totalCount=9, take(3) → skip=6: A1 (size 4) skipped via the size-sum arm, A2 enters with skipsLeft=2 → drains 2, pushes 3, returns true. Exercises both the whole-archetype-skip and partial-archetype + early-exit paths. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR b42a952 (daslib: tighten unsafe usage) condensed the enum-name lookup loop to a single `return unsafe(reinterpret<EnumTT>(ef.value)) if (name == ef.name)`, which left `var res : auto(EnumTT) = default<EnumT>` as dead code — only used to bind `EnumTT` (an alias of `EnumT` since `default<EnumT>` has type `EnumT`). Drop the dead var and inline the rename: `reinterpret<EnumTT>` → `reinterpret<EnumT>`. No behavior change. Verified by `tests/json/test_json_edge.das::test_enum_json` (128 tests pass; covers both the string-name path and the round-trip path at :630/:634). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…rivial-let-and-reverse-take linq_fold: trivial-let elision + reverse_take skip-into-tail — closes the m4 ladder
…dead-var-cleanup daslib: drop dead `var res` in json_boost.from_JV<EnumT>
For `from_decs._order_by(KEY).take(N).to_array()` with an inline-able key,
emit a bounded heap of size N maintained during the for_each_archetype walk
instead of materializing the full M-element buffer and then partial-sorting.
For `from_decs._order_by(KEY).first()` / `first_or_default(d)`, emit a
streaming-min: single `best` + `seen` flag instead of buf + min_by.
Cuts 100K push_clones (full DecsCar struct + string alloc) down to ~N
push_clones (only when the element wins the heap test).
Bench results (INTERP, 100K rows, ns/op):
sort_first_m4 72.0 → 23.9 (3.0×, BEATS m3f 41.3)
sort_take_m4 52.1 → 30.6 (1.7×, +7.9 vs m3f 22.7)
order_take_desc_m4 52.1 → 30.5 (1.7×, +8.2 vs m3f 22.3)
select_where_order_take_m4 35.1 → 25.1 (1.4×, +3.5 vs m3f 21.6)
Adds two thin re-exports in linq.das (`spliced_push_heap`, `spliced_pop_heap`)
so the splice can call sort_boost::{push,pop}_heap from any user module
without requiring sort_boost directly. The bounded-heap less-test uses a
new `make_inline_less_call` helper that templates the key body twice with
direct operand expressions — no block dispatch on the hot path.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
reserve(takeN) for a user-supplied take(N) on a decs source of unknown cardinality risks a large upfront allocation when N >> actual source size — same OOM trap that top_n_by_with_cmp's iterator variant already documents (linq.das:482-484). The fill phase grows geometrically to min(N, M) in O(log) reallocs anyway, and at our common N (≤100) the bench delta is in the noise floor (sort_take_m4 30.6 → 29.8, within measurement noise). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ecs-bounded-heap-order linq_fold: bounded-heap / streaming-min for plan_decs_order_family
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )