Skip to content

[pull] master from GaijinEntertainment:master#1036

Merged
pull[bot] merged 8 commits into
forksnd:masterfrom
GaijinEntertainment:master
May 26, 2026
Merged

[pull] master from GaijinEntertainment:master#1036
pull[bot] merged 8 commits into
forksnd:masterfrom
GaijinEntertainment:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 26, 2026

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 : )

borisbat and others added 8 commits May 25, 2026 12:51
Three small splice arms, bundled because they're independent. Closes
Theme 8 of benchmarks/sql/linq_fold_chain_audit.md and with it the
entire audit (all 8 themes shipped between 2026-05-24 and 2026-05-25).

* 2a (plan_reverse): each(arr).reverse()._distinct[_by](K).to_array()
  on array source. Backward index walk + table<K> set-gate. Saves
  cascade's reverse_to_array allocation AND distinct_by_inplace pass.

* 3b (plan_order_family): _distinct[_by] + _order_by[_descending]
  WITHOUT take. Existing where_+order fused-loop path generalized with
  var order_dset table + set-gated pushExpr (mirrors Theme 3 Phase 3
  bounded-heap gate). Composes with WHERE and terminal _select.

* C4 (plan_zip): trailing reverse as last chain op. Array lane emits
  reverse_inplace before return; counter/accumulator/any/all/contains
  lanes treat reverse as identity. Bails on first/first_or_default.

+16 tests / 16 sub-runs in test_linq_fold_theme8_fusion_arms.das,
including parity tests vs handwritten cascades and anti-tests for
each out-of-scope shape (2a-take, 3b-first, C4-first, C4-not-last).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot R1 (2 comments): both `var rev_dset` (2a) and `var order_dset`
(3b) should be `var inscope` to match the existing bounded-heap distinct
gate (linq_fold.das:1558/1562) and the rest of this file (plan_distinct,
plan_group_by_core). Without `inscope`, the dedup table's backing
storage isn't deterministically finalized on scope exit.

Post-fix AST dump confirms both emissions now include
`var inscope <name>/*used_in_finally*/` + a `finally __::builtin\`finalize\`
block, matching the bounded-heap path's emission shape.

CI failure (`build` job, Sphinx LaTeX): `linq_fold_patterns.rst:206`
flagged 'Unknown target name: "where"' — my 2a row had `where_/select/take`
as plain text and Sphinx parses trailing-underscore as a reference
target. Wrapped each token in backticks so it parses as code, not a
reference.

Verified: local sphinx-build -W --keep-going -b latex passes clean;
36/36 Theme 8 tests still green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…heme8-fusion-arms

linq_fold: Theme 8 — three specialized fusion arms (closes audit)
A bare integer literal like 1, -13, 0xFF now silently promotes to any
fitting numeric target type (int8/16/64, uint8/16/32/64, bitfield/8/16/64,
float, double) at infer time. examples/wip.das goes from 9 errors to 1
(the genuine `d : uint8 = 256` range overflow).

Mechanism: tryPromoteConstInt(expr, targetType, &rangeErr) called at
every canCopyOrMoveType-style site BEFORE the existing type-mismatch
check. On success, returns a new ExprConst* of the target type with
promotedFromInt=true and reportAstChanged; on range failure, emits
exceeds_constant_range (new code 30515) and the caller skips the
downstream cant_copy/mismatching_clone_type/mismatching_numeric_type.

Sites plumbed (12 in total):
- visit(ExprCopy/ExprClone/ExprOp2) — assignment, clone, binary ops
- visit(ExprReturn) — return type known from function signature
- visitLetInit / visitGlobalLetInit / preVisitStructureField — var inits
- visitMakeStructureField (struct + handle) / visitMakeVariantField /
  visitMakeTupleIndex / visitMakeArrayIndex — make-* element typing

Helper also recognizes ExprOp1("-", ExprConstInt|UInt) so promotion
works when const-folding is disabled (MCP lint flow runs with
no_infer_time_folding=true). The same-baseType bail keeps existing
uint-wrapping idioms like -1u intact.

Out of scope this PR (deferred to follow-ups):
- Function-call argument promotion (adds overload-disambiguation surface)
- Int -> enum (enums stay explicit by design)
- Tuple/array literal targets via var-init (var t : tuple<uint8;uint8>
  = (256, 0)) — the inner Make*Index plumbing is correct, but the outer
  tuple/array's recordType isn't propagated from var->type today

LINT011 — int -> float/double precision loss. The check is decided at
the promotion site (int64_t(float(value)) == value), result stamped onto
the new ExprConstFloat/Double as inexactFloatPromotion. LintVisitor's
visitExprConstFloat/Double reads that bit and emits the warning. Double
sources currently never trip the bit (uint32 max fits 2^53 exactly) —
wired symmetrically so future broader sources stay covered.

Other cleanups bundled because they're free:
- daslib/lint.das: dropped 19 redundant `self->` qualifiers (STYLE028)
  flagged by the lint sweep on this PR's diff
- utils/lint/main.das: skip `_*.das` fixture files (matches dastest's
  discovery rule and the existing dir skip); also fix one pre-existing
  PERF020 (`int('0')` → `'0'`)

Tests:
- tests/promote/test_promote.das — 9 positive subtests across all
  source types, target types, and call sites
- tests/promote/failed_*.das — 15 negative tests, one per plumbed site
  (each asserts `expect 30515` only — the suppression discipline IS
  the contract)
- tests/lint/test_lint011.das + _lint011_fixture.das — exact vs inexact
  promotion + // nolint:LINT011 suppression
- tests/aot/CMakeLists.txt — registered tests/promote AOT target

Docs:
- doc/source/reference/language/datatypes.rst — new "Integer literal
  promotion" subsection, softened opening claim, rewrote "What is NOT
  allowed"
- doc/source/reference/language/lint.rst — new LINT011 section

Verified: 9521/9521 interpreter tests pass, 8865/8865 AOT tests pass,
lint clean on every changed .das file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`type<T>` is a valid type in daslang (canonical witness-parameter form,
e.g. `t : type<auto(T)>` in clargs.das and elsewhere). The tree-sitter
grammar only recognized it inside `_type_macro_arg` (the inner sequence
of a `padded(type<T>, ...)` macro call) and as `type_expression` (which
appears in expression positions only). Function parameters, return
types, and struct fields declared with `type<T>` therefore fragmented
the parse -- breaking syntax highlighting in Zed and any other editor
using this grammar.

Add a dedicated `type_witness` rule mirroring bison's
`DAS_TYPE '<' type_declaration '>'` production (ds2_parser.ypp:3281)
and add it to `_type`. Reuse from `_type_macro_arg`. The existing
`type_expression` rule stays -- it remains the expression-context form
(e.g. `let x = type<int>`), and the conflict declaration is updated
to `[type_expression, type_witness]`.

Five new corpus tests cover: basic param, auto generic param (the bug
report case), return type, struct field, nested. All 34 corpus tests
pass; the previous 29 are unchanged.

parser.c regen also reflects a CLI version bump (the 0.22.0 cli no
longer runs on Node 24, so generation used 0.26.9 with ABI 14).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ExprConstT::clone copied only `value`, dropping `foldedNonConst`,
`promotedFromInt`, and `inexactFloatPromotion`. Any post-clone paranoid
lint pass would lose LINT011 firing on a promoted-then-cloned literal.
Same gap in ExprConstEnumeration::clone and ExprConstString::clone.

Fix: add ExprConst::clone virtual that copies the const-specific fields
once. The three concrete clones now route through it instead of calling
Expression::clone directly. Also picks up the latent foldedNonConst bug.

Bump AstSerializer wire version 85 -> 86: serializeConst now writes the
two new bools, so pre-PR cached archives would misalign on read without
the version bump.

Also:
- Remove dead tuple-element plumbing from visitMakeTupleIndex. Three
  different shapes (`var p : tuple<f;d> = (1,2)`, struct-field-of-tuple
  init, function arg) all reach the visitor with `recordType == nullptr`
  because surrounding type context isn't propagated into make-tuple. The
  promotion branch was unreachable.
- Add positive + negative array-element promotion tests for the (real,
  reachable) `visitMakeArrayIndex` path. Mixed-element literal like
  `[1.0f, 2, 3, 16777216]` exercises it; `[uint8(0), 100, 256, 200]`
  triggers exceeds_constant_range on element 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ness

tree-sitter: fix type<T>; parse failure in type position
…-literal

infer: implicit int-literal promotion + LINT011 precision warning
@pull pull Bot locked and limited conversation to collaborators May 26, 2026
@pull pull Bot added the ⤵️ pull label May 26, 2026
@pull pull Bot merged commit 0e6e33e into forksnd:master May 26, 2026
@pull pull Bot had a problem deploying to github-pages May 26, 2026 02:58 Error
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant