mouse-data/docs: 21 new + 1 updated card from linq_fold + dasImgui PR #38#2692
Conversation
…ssion Cards added in the course of the linq_fold splice rewrite + PR #2691 (has_sideeffects + counter-lane elision). Topics: linq_fold / macro-emission patterns: - daslang-generic-instance-detect-via-fromgeneric — func.fromGeneric is the canonical "which generic was this instantiated from?" link; func.name on typed instances is mangled. - daslib-macro-boost-has-sideeffects-predicate — new public predicate, full classification table, known limitations, test plumbing. - qmacro-invoke-source-bind-typedecl-modifier-iter-vs-array — typedecl block-param const/ref handling differs between iterator and array sources; the two diagnostic error messages tell you which branch you picked wrong. - qmacro-gensym-per-callsite-via-lineinfo — backtick-prefixed names + line+column suffix, force_at / force_generated / can_shadow. - my-fold-macro-emits-a-loop-with-for-it-in-source-... (UPDATED) — peel_each pattern corrected for generic-instance detection + positive array gate + block-param typedecl handling. LINQ semantics: - are-there-parity-tests-in-tests-linq-that-compare-fold-output-to-... - which-typedecl-predicates-identify-types-where-length-expr-is-... - why-does-each-arr-fail-with-unsafe-when-not-source-of-for-loop-... - what-s-the-right-sqlite-linq-chain-form-for-aggregates-sum-min-max-... - my-macro-substitutes-it-for-a-projection-expression-via-template-... - when-a-call-macro-needs-to-pick-copy-vs-move-init-for-a-projection-... - where-does-nolint-rule-go-when-a-lint-warning-is-emitted-from-inside-... Tooling / ops: - how-do-i-run-dastest-in-benchmark-only-mode-and-what-s-the-command-... - cpp-profiler-macos-samply-instruments.md - what-s-the-end-to-end-checklist-for-adding-a-new-daslib-das-module-... - how-do-i-call-a-dasimgui-or-any-managed-c-method-on-a-struct-field-... Updated: - why-does-my-dastest-integration-test-hang-at-readiness-gate-failed-... — original card pointed at a require-order red herring; real cause was ref_time_ticks() returning ns on POSIX while wait_until_ready's deadline math assumed μs. Fix landed in PR #2685. No code changes — docs only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five cards captured while landing dasImgui PR #38 — the dastest integration suite running across the 3-OS GitHub Actions matrix. Docs-only — no code changes. - imgui-playwright-windows-ci-16-post-libhv-stall — dasHV/libhv on GitHub-hosted windows-latest stalls after exactly 16 POST /command per subprocess. Empirically counted from DASLIVE_HV_LOG=stderr logs. Local Win11 unaffected. Workaround: 1-POST polling helpers + Windows-only --exclude of 7 high-POST tests with a 4-call safety margin. - imgui-harness-headless-timeout-sec-cascade-guard — new --headless-timeout-sec=N CLI flag on the imgui_harness 5-helper surface. Playwright passes (test_timeout - 5) so a panicked test can't leave a zombie daslang-live holding port 9090 (daslang's `finally` is skipped on panic). Cascade-prevention pattern generalizes to any spawned-subprocess-owning-a-port layout. - imgui-macos-configmacosxbehaviors-shortcut-is-super-not-ctrl — ImGui sets io.ConfigMacOSXBehaviors = true on macOS; the "shortcut key" becomes Super (Cmd), not Ctrl. Synth-IO tests must branch on snap?["io"]?["config_macos_behaviors"] and use ["Super"] mods on macOS. Surfaced after the cascade-fix made the symptom observable; Copilot diagnosed it via config_macos_behaviors snapshot extension. - why-does-daslang-live-s-post-shutdown-return-200-ok-but-the- subprocess-never-actually-exits-on-linux-macos — libhv v1.3.4 `pathHandlers` is std::unordered_map; ANY("*") catch-all enumerates BEFORE specific paths on Linux libstdc++, intermittently on Windows MSVC. Every request hits the help handler, /shutdown's request_exit() never runs. Workaround landed via daslang PR #2688 (drops ANY, serves help from GET("/")). Upstream libhv bug unreported as of 2026-05-16. - why-does-my-lint-macro-fire-on-the-wrapper-module-that- legitimately-uses-the-forbidden-symbols-even-though-i-scope- visit-module — [lint_macro] runs PER MODULE during the require chain; getThisModule rebinds per per-module pass, so visit_module(prog.getThisModule) ALSO walks the wrapper that legitimately uses the forbidden symbols. Wrapper modules must carry the defensive opt-out (options _allow_xxx_calls = true), same convention as imgui_lint.das's _allow_imgui_legacy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Docs-only update adding a batch of new “mouse-data” knowledge cards captured during the linq_fold splice rewrite work, plus one correction to an existing readiness-gate troubleshooting card.
Changes:
- Added 16 new documentation cards covering
linq_fold/macro-emission patterns, LINQ semantics questions, and a few tooling/ops notes. - Updated the existing “readiness gate FAILED” troubleshooting card to correct the root-cause explanation and recommended fix patterns.
- Added cross-links between related cards for the
each(...)peeling / typedecl-modifier / side-effect detection topics.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| mouse-data/docs/why-does-my-dastest-integration-test-hang-at-readiness-gate-failed-when-external-curl-to-status-works-fine-is-it-a-require-order.md | Updates readiness-gate troubleshooting write-up with corrected root cause and fix guidance. |
| mouse-data/docs/why-does-each-arr-fail-with-unsafe-when-not-source-of-for-loop-outside-a-for-and-what-s-the-alternative-in-a-linq-chain.md | New card explaining each(arr) safety constraints and alternatives in pipe chains. |
| mouse-data/docs/which-typedecl-predicates-identify-types-where-length-expr-is-statically-resolvable-in-daslang-macros.md | New card summarizing TypeDecl predicates relevant to emitting length(...) from macros. |
| mouse-data/docs/where-does-nolint-rule-go-when-a-lint-warning-is-emitted-from-inside-a-qmacro-expr-and-fires-at-the-user-s-call-site-rather-than.md | New card documenting correct // nolint: placement for lint reports originating inside qmacro_expr. |
| mouse-data/docs/when-a-call-macro-needs-to-pick-copy-vs-move-init-for-a-projection-should-i-emit-static-if-typeinfo-is-workhorse-e-proj-or-decid.md | New card advising macro-time _type branching vs runtime static_if for workhorse decisions. |
| mouse-data/docs/what-s-the-right-sqlite-linq-chain-form-for-aggregates-sum-min-max-average-and-what-operators-aren-t-supported-as-sql-chain-term.md | New card describing sqlite_linq aggregate terminal forms and unsupported terminal patterns. |
| mouse-data/docs/what-s-the-end-to-end-checklist-for-adding-a-new-daslib-das-module-so-docs-build-cleanly.md | New card outlining doc-generation registration steps for new daslib/*.das modules. |
| mouse-data/docs/qmacro-invoke-source-bind-typedecl-modifier-iter-vs-array.md | New card explaining how to choose typedecl modifiers for invoke source binding (iterator vs array). |
| mouse-data/docs/qmacro-gensym-per-callsite-via-lineinfo.md | New card showing a LineInfo-based gensym pattern for per-callsite identifiers in macros. |
| mouse-data/docs/my-macro-substitutes-it-for-a-projection-expression-via-template-replacevariable-it-proj-apply-template-but-the-result-fails-to.md | New card describing the ExprRef2Value substitution trap with Template.replaceVariable + apply_template. |
| mouse-data/docs/my-fold-macro-emits-a-loop-with-for-it-in-source-acc-reserve-length-source-but-the-reserve-doesn-t-fire-when-the-chain-starts-wi.md | New/rewritten card documenting each(<array>) peeling and correct gating for reserve/length optimizations. |
| mouse-data/docs/how-do-i-run-dastest-in-benchmark-only-mode-and-what-s-the-command-line-syntax.md | New card documenting dastest benchmark-only CLI invocation patterns. |
| mouse-data/docs/how-do-i-call-a-dasimgui-or-any-managed-c-method-on-a-struct-field-that-s-bound-as-a-raw-pointer-e-g-addfontfromfilettf-on-getio.md | New card explaining how to call methods on managed C++ struct fields bound as raw pointers. |
| mouse-data/docs/daslib-macro-boost-has-sideeffects-predicate.md | New card documenting has_sideeffects(expr) and intended usage/limitations. |
| mouse-data/docs/daslang-generic-instance-detect-via-fromgeneric.md | New card explaining func.fromGeneric for identifying specialized generic calls. |
| mouse-data/docs/cpp-profiler-macos-samply-instruments.md | New card recommending macOS C++ sampling profiler workflows for daslang. |
| mouse-data/docs/are-there-parity-tests-in-tests-linq-that-compare-fold-output-to-the-underlying-linq-operators.md | New card describing where LINQ operator parity coverage effectively lives in the test suite. |
Comments suppressed due to low confidence (3)
mouse-data/docs/why-does-each-arr-fail-with-unsafe-when-not-source-of-for-loop-outside-a-for-and-what-s-the-alternative-in-a-linq-chain.md:36
- This document has two separate "## Questions" sections at the end, which results in duplicated content. Please keep a single "## Questions" block and remove the second header + repeated question.
## Questions
- Why does `each(arr)` fail with "unsafe when not source of for-loop" outside a for, and what's the alternative in a linq chain?
- error[31013] '__::builtin`each`' is unsafe — how to fix?
- When can I use `each(arr)` in a linq pipe chain?
## Questions
- Why does `each(arr)` fail with "unsafe when not source of for-loop" outside a for, and what's the alternative in a linq chain?
mouse-data/docs/what-s-the-right-sqlite-linq-chain-form-for-aggregates-sum-min-max-average-and-what-operators-aren-t-supported-as-sql-chain-term.md:40
- The document ends with a duplicated "## Questions" section (the first question is repeated under a second header). Please remove the second header + duplicate question.
## Questions
- What's the right sqlite_linq chain form for aggregates (sum/min/max/average), and what operators aren't supported as `_sql` chain terminals?
- Why does `_sum(_.price)` fail in `_sql` with "can't locate variable '_'"?
- How do I express `any`/`all`/distinct-count/take-count in `_sql`?
## Questions
- What's the right sqlite_linq chain form for aggregates (sum/min/max/average), and what operators aren't supported as `_sql` chain terminals?
mouse-data/docs/how-do-i-run-dastest-in-benchmark-only-mode-and-what-s-the-command-line-syntax.md:46
- There are two "## Questions" sections at the end (duplicated first question). Please remove the second header + repeated question to keep the doc clean and avoid duplicate indexing.
## Questions
- How do I run dastest in benchmark-only mode and what's the command-line syntax?
- What's the dastest --bench command line?
- How do I filter dastest benchmarks by name?
## Questions
- How do I run dastest in benchmark-only mode and what's the command-line syntax?
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| ## Questions | ||
| - Where does `// nolint:RULE` go when a lint warning is emitted from inside a `qmacro_expr` and fires at the user's call site rather than at the macro source? |
|
|
||
| ## Questions | ||
| - Are there parity tests in tests/linq/ that compare `_fold` output to the underlying linq operators? |
|
|
||
| ## Questions | ||
| - What's the end-to-end checklist for adding a new daslib/*.das module so docs build cleanly? |
| External `curl http://localhost:9090/status` from a sibling shell returns 200 with proper status JSON throughout — only the popen parent's poll loop "can't see it". Reproduces on macOS and Linux; appears to NOT reproduce on Windows (which is the trap — see below). | ||
|
|
||
| # Root cause | ||
|
|
||
| `live/live_api` was required BEFORE `imgui_app + glfw/glfw_boost + opengl/* + glfw_live + opengl_live` somewhere in the requirer chain (usually a wrapper module like `imgui/imgui_harness`). The `[_macro] installing` in `live_api.das` calls `fork_debug_agent_context(@@debug_agent)` at compile time. If that fork happens before GLFW is initialized in the live runtime, the resulting LiveApiServer becomes unreachable from a popen parent on Windows. | ||
| **`ref_time_ticks()` returns nanoseconds on POSIX, but the wait-loop math assumes microseconds.** | ||
|
|
||
| Filed: [#2677](https://github.com/GaijinEntertainment/daScript/issues/2677). Distinct from #2675 (`ANY("*")` route shadowing). | ||
| `src/hal/performance_time.cpp` defines `ref_time_ticks()` per platform: | ||
|
|
||
| # Fix (mechanical) | ||
| | Platform | Returns | | ||
| |---|---| | ||
| | Linux | `tv_sec * 1e9 + tv_nsec` — **nanoseconds** | | ||
| | macOS | `clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)` — **nanoseconds** | | ||
| | Windows | `QueryPerformanceCounter().QuadPart` — counter ticks, freq depends on hardware (often ~10 MHz, accidentally close to 1 MHz / microsecond scaling) | | ||
|
|
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Done in c24e4b5. Updated the card to reflect current performance_time.cpp reality:
- Table Windows row: now shows nanoseconds via QPC→ns conversion (PR ref_time_ticks: normalize to nanoseconds on every platform #2685), with a note that pre-PR ref_time_ticks: normalize to nanoseconds on every platform #2685 returned raw
QuadPartticks (~10 MHz, accidentally near μs scaling) - Root-cause headline: "nanoseconds on POSIX" → "nanoseconds on all platforms (post-PR ref_time_ticks: normalize to nanoseconds on every platform #2685)"
- Windows bullet in the explanation: split into pre/post-PR ref_time_ticks: normalize to nanoseconds on every platform #2685 so the "masks the bug by accident" narrative is correctly scoped to the old behavior
- Symptom description and "How to recognize" bullet: "appears to NOT reproduce on Windows" scoped to pre-PR ref_time_ticks: normalize to nanoseconds on every platform #2685; current code shows the same failure on all platforms
- Option B in the Fix section: the per-platform caveat dropped for post-PR ref_time_ticks: normalize to nanoseconds on every platform #2685 builds (noted for older builds)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… post-PR #2685 ns normalization Agent-Logs-Url: https://github.com/GaijinEntertainment/daScript/sessions/97224dec-45d1-4968-a3dd-8e5f37274983 Co-authored-by: borisbat <272689+borisbat@users.noreply.github.com>
Summary
Cards added/refined across two parallel work streams that wrapped today:
Docs-only — no code changes.
What's in here
linq_fold / macro-emission patterns
func.fromGenericis the canonical "which generic was this instantiated from?" link.func.nameon typed instances is mangled.typedecl(...) [- const]handling differs between iterator (rvalue, needs-const) and array sources (const-ref, keep modifiers).`name`{at.line}`{at.column}pattern +force_at+force_generated+can_shadow.peel_eachpattern corrected: generic-instance viafromGeneric, positive array gate, branched block-param typedecl. Links to the two new related cards.LINQ semantics
Tooling / ops
Correction (existing card)
require-order red herring; real cause wasref_time_ticks()returning ns on POSIX whilewait_until_ready's deadline math assumed μs. Fix landed in PR ref_time_ticks: normalize to nanoseconds on every platform #2685. Companion: issue daslang-live: require order sensitivity — live/live_api before imgui_app/glfw_live breaks /status reachability from popen parent #2677 (which encoded the same misdiagnosis) closed as superseded.dasImgui PR #38 — CI matrix resurrection (5 new cards)
windows-lateststalls after exactly 16 POST /command per subprocess. Empirically counted fromDASLIVE_HV_LOG=stderrlogs. Local Win11 unaffected. Workaround: 1-POST polling helpers + Windows-only--excludeof 7 high-POST tests with a 4-call safety margin under the observed limit.--headless-timeout-sec=NCLI flag on imgui_harness. Playwright passes(test_timeout - 5)so a panicked test can't leave a zombie daslang-live holding port 9090 (daslang'sfinallyis skipped on panic). Cascade-prevention pattern generalizes to any spawned-subprocess-owning-a-port layout.io.ConfigMacOSXBehaviors = trueon macOS; the "shortcut key" becomes Super (Cmd), not Ctrl. Synth-IO tests must branch onsnap?["io"]?["config_macos_behaviors"]and use["Super"]mods on macOS. Surfaced after the cascade fix made the symptom observable.pathHandlersisstd::unordered_map;ANY("*")catch-all enumerates BEFORE specific paths on Linux libstdc++, intermittently on Windows MSVC. Every request hits the help handler,/shutdown'srequest_exit()never runs. Workaround landed via daslang PR live_api: drop ANY("*") catch-all (POSIX shutdown hang) #2688 (dropsANY, serves help fromGET("/")). Upstream libhv bug unreported as of 2026-05-16.[lint_macro]runs PER MODULE during the require chain;getThisModulerebinds per per-module pass, sovisit_module(prog.getThisModule)also walks the wrapper module that legitimately calls the forbidden symbols. Wrapper modules must carry the defensive opt-out (options _allow_xxx_calls = true), same convention asimgui_lint.das's_allow_imgui_legacy.Test plan
mouse__addso similarity-block already vetted (highest sim 0.10 for any new card)[[slug]]from the corrected fold card to the two new related cards🤖 Generated with Claude Code