Appearance
开发计划
如果你想先看当前真实已经支持到什么程度,而不是看后续应该怎么推进,请先阅读:当前支持基线。
如果你想看阶段归档与推进脉络,请再阅读:P1-P7 阶段总览。
如果你需要追溯旧版长文、逐轮切片记录和被收口掉的历史入口页,请看:路线图归档。
说明:本文保留了大量阶段推进时记录下来的样例路径。文中出现的
ramdon_tests/...指向的是crates/ql-cli/tests/executable_examples.rs约定的本地忽略 smoke 目录,不是当前 checkout 自带的已提交目录;当前真实基线请以代码、测试矩阵和 当前支持基线 为准。
这份文档的职责不是重复阶段归档,而是统一回答四个问题:
- Qlang 现在到底处于什么阶段
- 当前主线应该继续往哪里推进
- 后续阶段应该按什么顺序展开
- 每个阶段必须交付哪些横向工程结果
文档分工约定:
/roadmap/current-supported-surface负责“今天真实支持到哪里、哪些边界仍关闭”/roadmap/phase-progress负责“已经做到了什么”/plans/负责“各阶段是怎么设计和收口的”- 本页负责“接下来按什么顺序推进,哪些边界必须继续保守”
当前判断
截至 2026-04-07,Qlang 已经不是“只有语言设计文档的预研空壳”,而是一个真实的语言与工具链仓库;当前主编译器实现使用 Rust,但这不应倒置为“语言设计向 Rust 靠拢”:
- Phase 1 到 Phase 6 的基础设施已经在仓库中落地
- 当前主线工作是保守的 Phase 7:async/runtime/library-build/program-build/Rust interop
- 现阶段最重要的目标不是盲目扩语法,而是沿着现有边界持续扩展,不推翻已有真相源
- 文档、测试、实现必须继续保持同一事实面,否则项目会重新退化成“代码和路线图各说各话”
- 当前 Phase 8 的 editor 侧策略继续保持保守:优先补导入链路上真正阻塞编辑体验的
.qi消费与回退路径,例如当前文档临时报错时真实ql-lspbackend 上的 dependency import / variant / explicit struct-field completion,以及 imported dependency local name / dependency variant / struct-field token 与 dependency struct member-field / member-method token的最小 hover / definition / declaration / references 回退;dependency value root 现在也已在同一条 broken-source 回退链上补齐最小 hover / definition / declaration / references,当前覆盖 parse-only 可恢复的 dependency named local、inline tuple/arrayforloop binding 与impl/extend方法体selfreceiver,并继续固定跳到 dependency public struct declaration 与当前文件内的同 binding 局部引用;显式 type use 上的最小textDocument/typeDefinition如今也已补到 dependency import/type-root 的 broken-source fallback,并小步扩到 dependency enum variant token 到 enum declaration 的跳转、语法局部可恢复的 dependency struct value root、dependency struct field token 的字段声明类型跳转,以及 dependency method token 的返回类型跳转;field/method token 如果直接接?,当前也会优先跳到Option[T]/Result[T, E]解包后的 dependency public type。同一条 receiver truth surface 上的 dependency field / method completion 现也已开放,并继续扩到 dependency method-call result local、direct dependency field-projection result local、struct destructuring / match destructuring 派生的 dependency local、inline tuple/arrayforloop binding、?解包后的 dependency receiver、收敛到同一个 dependency struct 的 block/if/match 结果表达式、不经命名 local 的 direct dependency field-projection / method-call / structured receiver,以及 target 可唯一恢复为 dependency struct 的impl/extend方法体selfreceiver;而同一条 receiver/identity 真相源现在也已把 inline tuple/arrayforloop binding 接到 dependency field/method query 与 broken-source value-root references 上。同一条 completion bridge 现在也已开始直接向 LSP 暴露 declaration snippet/type markdown documentation,减少“能补全但看不清合同”的编辑摩擦,而 dependency member-field / member-method completion 现在也已补齐字段类型 / 返回类型。declaration request 也已正式接到同一条真相源上,而 same-file document symbol outline、以打开 package 为根的保守workspace/symbol(现已扩到同包源码 modules、同 workspace 的其它 member package 源码 modules,以及已加载 dependency.qipublic symbols;当前包因 source diagnostics 暂时失败时也会保留 dependency / sibling-member 搜索),以及显式 type use 上的最小textDocument/typeDefinition也已并回同一份 analysis 索引;同时,声明文件入口侧的ql project emit-interface现也已支持从 workspace-only 根 manifest 批量写出成员包默认.qi,并新增--changed-only跳过valid接口、--check只校验默认接口状态;其中 workspace--check现会汇总全部无效 member interface 并输出摘要;ql check/ql check --sync-interfaces也已支持从 workspace-only 根 manifest 批量检查成员包并同步依赖接口,而ql project graph现在也可直接暴露 package/member 默认.qi的路径/状态与引用 interface 状态,并用stale标记已被 manifest/源文件更新超过的声明产物;当前ql check也已把 stale dependency interface 收口成显式失败合同,而--sync-interfaces只重发非valid依赖,下一步仍应沿这份 receiver/identity 真相源小步扩真正需要的 symbol contract,而不是提前扩写 full workspace rename / code action - 同一条 Phase 8 editor strategy 的最新已交付切片,是把 dependency
forloop receiver 从 direct tuple/array root 继续扩到 structured iterable root:block/unsafe/if/match只要最终仍收敛到同一个 dependency tuple/array element binding,就继续复用同一 receiver identity。这也验证了当前最有效的推进方式,仍然是扩已有真相源,而不是为每个语法壳再写一套独立 query path。 - 下一层同构扩面也继续遵守这个原则:不是为
for current in items单独开新 special case,而是让 named iterable alias 也回到同一份 receiver identity 真相源。这样let items = (config, config)、let items = if flag { ... }、let items = match flag { ... }后再进入for current in items,依旧走同一条 dependency completion / query / fallback 合同。 - 同一条推进原则这一轮也继续覆盖到了 helper-return iterable:不是再为
for current in configs(config)/for current in children(config)另写 query 分支,而是让同文件 free function 的显式 tuple/array 返回类型重新落回既有 dependency element binding 真相源;这样 helper-return root 也能直接复用forreceiver completion / query / fallback 合同。 - 下一层同构扩面继续沿同一原则推进到 dependency method-return iterable:
for current in config.children()/for current in config.pair()这类 root 也不再单独写 special case,而是复用 dependency method metadata 里可恢复出的 iterable element binding,继续落回同一份forreceiver truth source。 - 同一条推进原则也继续扩到了 dependency field iterable:
for current in config.children/for current in config.pair这类 root 同样不再另写 ad-hoc query path,而是复用 dependency field metadata 里可恢复出的 iterable element binding,继续落回同一份forreceiver truth source。 - 同一条推进原则现在也继续扩到了 question-wrapped iterable root:
for current in config.children?/for current in config.pair()?这类 root 同样不单独分叉 query path,而是复用 field/method 元数据里可恢复出的解包后 iterable element binding,继续落回同一份forreceiver truth source。 - 同一条推进原则现在也继续扩到了同文件本地 receiver method iterable root:
for current in config.children()/for current in self.pair()这类 root 也不再另写 ad-hoc query 分支,而是复用当前 module 中impl/extend方法的显式返回类型,继续落回同一份forreceiver truth source。 - 同一条推进原则现在也继续扩到了 structured question root:
for current in (if flag { config.children? } else { config.children? })/for current in match flag { true => config.pair()?, false => config.pair()? }这类 root 同样不再另写 special case,而是让 structured root 继续复用 question-wrapped iterable binding,落回同一份forreceiver truth source。 - 当前 Phase 8 的 cross-file completion 扩面也继续遵守同一原则:优先补 imported dependency root 上真正可消费的 public surface,例如 public enum variant completion 与 explicit struct field-label completion,而不是直接承诺完整 dependency member/type-space completion
- 同一条 Phase 8 路线也继续要求 query contract 成片推进:某个 imported dependency root 一旦开放 completion,就优先把同一层级上最基本的 hover / definition 一并补齐,再决定是否继续扩 references
- sync backend 的首个
String闭环现已扩到真实 build 面:UTF-8 string literal 现可 lowering 为{ ptr, i64 }并经过 local/const/static/param/return/==/!=/ordered compare、ordinary stringmatcharm、ordinary capturing-closure string-match selected call roots(现已含最小 bool-guarded 子集)、cleanup direct match / cleanup-call match(现都含 same-fileconst/staticpath pattern + catch-all dispatch)与 aggregate transport 进入 LLVM/object build;与此同时,capturing sync closure 也已开放 immutable same-functionStringbinding capture 的最小子集;后续关于String的推进应优先放在更广义 string pattern、broader guarded closure-selection、runtime/ABI 与更完整数据模型等真实语言能力,而不是继续扩写 coverage-only 变体 - capturing closure value flow 现也补上了首个 task-handle transport 子集:sync closure 现在已可捕获 immutable same-function
TaskHandlebinding,并经 ordinary direct local / local alias call、ordinaryif/ integer-match选出的 direct root / local binding root,以及 cleanup awaited-root 的最小 direct/local-binding matrix,把 handle 返回给外层或 cleanup 内部的 localawait;当前defer if await ...与defer match await ...都已同时接受 direct root / local binding root,并已进一步开放首个 block-local alias tail / local alias chain cleanup-awaited root 子集、首个 different-closure cleanup-awaited control-flow 子集、这条 different-closure path 上的首个 block-binding / local-alias-chain 变体、首个 helper/inline awaited-value cleanup control-flow 子集、首个 nested runtime projection awaited-value cleanup control-flow 子集、首个 awaited aggregate current-binding scrutinee cleanup control-flow 子集、首个 awaited aggregate destructuring scrutinee cleanup control-flow 子集,以及首个 awaited fixed-array destructuring scrutinee cleanup control-flow 子集,例如defer { sink(match await (if ... { left } else { right })() { [first, _, last] => ... }) }与defer match await (match ... { true => left, false => right })() { [first, middle, last] if first == 30 => ... },外加首个 shared-local control-flow assignment-valued binding alias-chain cleanup-awaited 子集(现已包含 bool-match、guarded-match与 tagged/binding-pattern guardedmatch三类等价 control-flow,其中 bool / guarded / tagged 版本都已各自补上至少一个 shared-local 或 different-closure alias-root 变体);与此同时 guarded-match与 tagged/binding-pattern guardedmatch现在都已补上首个 different-closure cleanup-awaited root 子集及其首个 block-binding / local-alias-chain 版本;后续关于 task-handle callable transport 的推进,应优先放在更广义的 cleanup control-flow 形态与更完整的 async callable contract,而不是只补更多等价变体 - sync backend 的普通 bind-pattern lowering 现也已进入真实扩容:ordinary
let、fixed-shapefor与 fixed-shapefor await的binding/_/ tuple / struct / fixed-array destructuring pattern 都已接入当前 LLVM build surface,后续继续沿这类“前端已存在、后端仍保守拒绝”的缺口推进 - ordinary / cleanup direct / projected / nested projected / same-file import-alias projected / same-file import-alias nested projected / control-flow selected projected / control-flow selected nested projected / same-file import-alias control-flow selected projected / same-file import-alias control-flow selected nested projected / call-root / same-file import-alias call-root / control-flow selected call-root / same-file import-alias control-flow selected call-root / nested call-root projected / same-file import-alias nested call-root projected / control-flow selected nested call-root projected / same-file import-alias control-flow selected nested call-root projected loadable
matchcatch-all 这轮也已正式对齐到 tuple / struct / fixed-array destructuring:match (1, 2) { (left, right) => ... }、match current { State { value } => ... }、match [1, 2, 3] { [first, _, last] => ... },以及match bundle.pair { (left, right) => ... }、match bundle.current { State { value } => ... }、match bundle.values { [first, _, last] => ... }、match tuple_env.outer.payload.values { (left, right) => ... }、match state_env.outer.payload.current { State { value } => ... }、match array_env.outer.payload.values { [first, _, last] => ... }、match bundle_alias.pair { (left, right) => ... }、match bundle_alias.current { State { value } => ... }、match bundle_alias.values { [first, _, last] => ... }、match tuple_alias.outer.payload.values { (left, right) => ... }、match state_alias.outer.payload.current { State { value } => ... }、match array_alias.outer.payload.values { [first, _, last] => ... }、match (if branch { tuple_left } else { tuple_right }).outer.payload.values { (left, right) => ... }、match (match branch { true => state_left, false => state_right }).outer.payload.current { State { value } => ... }、match (if branch { array_left } else { array_right }).outer.payload.values { [first, _, last] => ... }、match (if branch { left_bundle_alias } else { right_bundle_alias }).pair { (left, right) => ... }、match (match branch { true => left_bundle_alias, false => right_bundle_alias }).current { State { value } => ... }、match (if branch { left_bundle_alias } else { right_bundle_alias }).values { [first, _, last] => ... }、match (if branch { left_tuple_alias } else { right_tuple_alias }).outer.payload.values { (left, right) => ... }、match (match branch { true => left_state_alias, false => right_state_alias }).outer.payload.current { State { value } => ... }、match (if branch { left_array_alias } else { right_array_alias }).outer.payload.values { [first, _, last] => ... }、match (if branch { left } else { right }).pair { (left, right) => ... }、match (match branch { true => left, false => right }).current { State { value } => ... }、match (if branch { left } else { right }).values { [first, _, last] => ... }、match pair_value() { (left, right) => ... }、match state_value() { State { value } => ... }、match values() { [first, _, last] => ... }、match pair_alias() { (left, right) => ... }、match state_alias() { State { value } => ... }、match values_alias() { [first, _, last] => ... }、match (if branch { pair_value } else { alt_pair_value })() { (left, right) => ... }、match (match branch { true => state_value, false => alt_state_value })() { State { value } => ... }、match (if branch { values } else { alt_values })() { [first, _, last] => ... }、match (if branch { pair_alias } else { alt_pair_alias })() { (left, right) => ... }、match (match branch { true => state_alias, false => alt_state_alias })() { State { value } => ... }、match (if branch { values_alias } else { alt_values_alias })() { [first, _, last] => ... }、match tuple_env(1).payload.values { (left, right) => ... }、match state_env(3).payload.current { State { value } => ... }、match deep_env(6).outer.payload.values { [first, _, last] => ... }、match tuples(1).payload.values { (left, right) => ... }、match states(3).payload.current { State { value } => ... }、match deep(6).outer.payload.values { [first, _, last] => ... }、match (if ... { tuple_env } else { alt_tuple_env })(1).payload.values { (left, right) => ... }、match (match ... { true => state_env, false => alt_state_env })(3).payload.current { State { value } => ... }、match (if ... { deep_env } else { alt_deep_env })(4).outer.payload.values { [first, _, last] => ... }、match (if ... { tuples } else { alt_tuples })(1).payload.values { (left, right) => ... }、match (match ... { true => states, false => alt_states })(3).payload.current { State { value } => ... }与match (if ... { deep } else { alt_deep })(4).outer.payload.values { [first, _, last] => ... }这类 projected-root / nested-projected-root / same-file-import-alias-projected / same-file-import-alias-nested-projected / control-flow-selected-projected / control-flow-selected-nested-projected / same-file-import-alias-control-flow-selected-projected / same-file-import-alias-control-flow-selected-nested-projected / call-root / import-alias-call-root / control-flow-selected-call-root / same-file-import-alias-control-flow-selected-call-root / nested-call-root-projected / import-alias-nested-call-root-projected / control-flow-selected-nested-call-root-projected / import-alias-control-flow-selected-nested-call-root-projected 版本,连同对应的defer match版本,现在都已由独立的 driver LLVM IR 回归与ql build --emit objfixture 锁住,不再只是 backend 已支持、文档仅用“current-loadable scrutinee catch-all”笼统描述的隐式能力 - ordinary fixed-shape loop root 现也应按真实 build 面理解:普通
for与for await已不再只限 direct/projected/call-root 的最早子集,projected block/assignment/runtimeif/matchroots 也已进入当前 LLVM build surface - ordinary fixed-shape
for await的 task-producing item root 现也应按真实 build 面理解:same-fileconst/staticroot、same-file item alias root,以及 projected task item root 现在已进入 current LLVM build surface,而不再只由 inline task-array / task-tuple root 代表 - runtime task-backed item value flow 现也应按真实 build 面理解:same-file task-producing
const/staticitem 与 same-file alias,已经不再只限 root-levelfor await/ projectedawait入口,而是可以经过 ordinary local binding、sync helper 参数/返回值,以及 runtimeif/match选值后继续进入当前 async build surface - cleanup fixed-shape
for awaitroot 现也要按同样标准理解:current build surface 不再只限 direct/projected/awaited root,direct call-root、same-file import-alias call-root 与 nested call-root projected root 也已进入当前 LLVM build surface - cleanup fixed-shape
for await的 direct iterable root 也已扩到当前真实 build 面:block-valued、assignment-valued、runtimeif/match、以及 awaited direct fixed-shape root 都已进入 current LLVM build surface,而不再只由 direct local / projected family 代表 - cleanup fixed-shape
for await的 transparent?也已不再只限 projected family:direct fixed-shape array / tuple root 与 block-wrapped direct root 现在也已进入 current LLVM build surface - cleanup fixed-shape
for await的 item-backed scalar root 现也已进入 current LLVM build surface:same-file scalarconst/staticroot、same-file scalar item alias、以及 item-backed read-only projected scalar root 现在都能稳定 build - cleanup fixed-shape
for await的 task-producing item root 现也已进入 current LLVM build surface:same-fileconst/staticroot、same-file item alias root,以及 projected task item root 现在都能稳定 build,而不再只由 inline task-array / task-tuple root 代表 - cleanup runtime task-backed item value flow 现也已进入 current LLVM build surface:same-file task-producing
const/staticitem 与 same-file alias,当前也可经过 cleanup local binding、sync helper 参数/返回值,以及 runtimeif/match选值后继续进入 projectedawait/ cleanupfor await - cleanup branch body 现也应按真实 build 面理解:cleanup
if/match分支已经不再只限 call-backed expr,而是可以承载当前已开放的 cleanup block 语句子集,包括 local binding 与 asyncfor await - runtime callable value flow 现也应按真实 build 面理解:ordinary / cleanup value path 里的 runtime
if/match已不再只限挑选 scalar / aggregate value;当前 same-file function item / alias、callableconst/static/ alias,以及 closure-backed callableconst/static/ alias,也可以作为 typed callable value 被选出并继续间接调用;对应的 same-file async function item / alias 与 async callableconst/static/ alias,也可以继续进入 localawait与 cleanup value-pathawait - sync closure value flow 现也应按真实 build 面理解:当前不再只剩 non-capturing 形态,首个 capturing 子集已经进入 LLVM build surface;边界现收窄在 non-
move、immutable same-function scalar /Stringbinding capture、原局部 direct ordinary call、local alias ordinary call(含 same-target mutable reassign)、assignment-valued same-target ordinary direct callee root、control-flow 收敛到 same-target assignment-valued / block-local alias tail ordinary callee root、ordinary local binding 后再调用的 control-flow-selected / block-local assignment-valued / control-flow-assignment-valued / block-local alias tail binding root / local alias chain、local alias cleanup callee、local alias cleanup guard-call、assignment-valued cleanup callee / guard-call root、cleanup block 内局部 alias 的 direct call / guard-call(现含 statement-sequenced local mutable alias same-target reassign、statement-sequenced cleanup block 内局部 mutable alias 的 different-target reassign、assignment-valued same-target binding、control-flow 收敛到 same-target assignment-valued root 的 binding,以及 control-flow 分支内的 block-local alias tail binding;同类 direct cleanup callee / cleanup guard-call root 现在也已接通,包含defer ({ var alias = left; alias = right; alias })(...)这类 block-local different-target mutable alias direct root),与 ordinarymatchguard-call(现含 direct callee root、先绑定到 ordinary local 后再调用的 control-flow-selected root、block-local assignment-valued / control-flow-assignment-valued binding root,以及 different-closure control-flow 下的 block-local alias tail / block binding / local alias chain callee root);与此同时,capturing sync closure 现在也已开放 immutable same-functionTaskHandlebinding capture 的最小 transport 子集:ordinary direct local / local alias call,以及 ordinaryif/ integer-match选出的 direct root / local binding root,可把 captured handle 继续交给外层 localawait;runtimeif/match在 ordinary direct/local-binding/cleanup paths 上现也已开放 same-target control-flow 子集,而 ordinary direct call、ordinary local binding root 及其后续 local alias chain 调用(现含后续未重写块)、ordinarymatchguard-call 与 cleanup callee / cleanup guard-call 现在都额外开放了首个 different-closure control-flow 子集,只要各分支仍落在 direct root / block-local alias tail / block binding / local alias chain root 子集;同一条 local mutable alias 的 different-target reassign 现在也已开放到 ordinary direct call、ordinary local binding root、ordinary control-flow assignment-valued direct/binding/alias-chain root、cleanup direct root、cleanup local binding root、ordinarymatchguard-call,以及 runtimeif/matchbranch-join 子集;其中 cleanupifshared-local control-flow assignment-valued binding alias-chain 已接通,cleanup boolmatch的等价 alias-chain 已接通,而 cleanup guardedmatch的等价 alias-chain 现在也已接通首个子集;其他 escape 路径仍关闭
总体原则
1. 尽早形成真实闭环
对 Qlang 来说,闭环从来不只是“parser 能跑”,而是至少包括:
- 有用户可执行的 CLI 路径
- 有稳定 diagnostics
- 有回归测试
- 有文档与示例
- 有明确的失败合同
2. 一层只维护一份真相源
- AST/HIR/resolve/typeck/MIR/codegen/runtime 各层只维护自己的事实
- CLI、LSP、FFI、文档不要复制实现层语义
- 能从共享 analysis/query/runtime contract 派生的内容,不要在边缘工具再写一套
3. 先把失败模型做对,再扩公开能力
- 保守拒绝比错误支持更可维护
- 诊断、回归和边界说明必须先于更宽的表面承诺
- async、ownership、FFI、editor semantics 都继续沿用这个原则
4. 编译器开发必须测试驱动
- 回归测试属于功能本身,不是收尾工作
- 新能力先补“最小必要回归”:至少锁住一个 blocker 和一个用户可见路径
- coverage-only 的相邻变体补洞不再作为主线,除非它们直接保护新功能或刚修掉的回归
5. C ABI 是当前稳定互操作边界
- C ABI 继续作为稳定外部边界
- Rust 互操作继续走 “Rust host <-> C ABI <-> Qlang” 路线
- 更深的 Rust effect/runtime 绑定、C++ 深度互操作都应后置
6. 文档要跟着实现一起推进
- 路线图、阶段总览、README、示例和测试结果必须同步
- 不允许 README 说一套、roadmap 说一套、代码里又是另一套
- 主入口页保持短版;逐轮细节与旧状态转入 archive,避免 roadmap 再次膨胀
7. 功能交付优先于 coverage-only 收口
- 当前主线优先解决“用户已经能写、前端已经能分析、但 backend 仍明确拒绝”的能力缺口
- 语言真实功能优先于测试矩阵扩写、文档润色和外围 UX 微调
- 每轮只同步必要文档:当前支持基线、当前开发计划,以及与该能力直接相关的设计页
8. 宿主实现语言不能反向定义 Qlang
- Rust 是当前编译器/工具链的实现语言,不是 Qlang 的语法模板
- Qlang 的语言身份以
docs/vision.md、docs/design/principles.md、docs/design/syntax.md为准 - 如果某条实现路径只是“更像 Rust 所以更容易写”,但会让语言边界变形,应回到设计文档重新校准
- 文档示例、路线图叙事、README 入口也必须遵守这条边界,避免把 Qlang 展示成 Rust 子集
已完成阶段(P0-P6)
这些阶段已经形成稳定地基。后续工作应该在其上扩展,而不是回头推翻。
| 阶段 | 状态 | 已形成的稳定边界 |
|---|---|---|
| Phase 0 | 已完成 | 语言定位、设计原则、仓库结构、阶段划分 |
| Phase 1 | 已完成 | lexer / parser / AST / formatter / CLI 前端最小闭环 |
| Phase 2 | 已完成 | HIR / resolve / typeck / diagnostics / 最小 query / 最小 LSP |
| Phase 3 | 已完成 | 结构化 MIR / ownership facts / cleanup-aware 分析 / closure groundwork |
| Phase 4 | 已完成 | ql build、LLVM IR、obj / exe / staticlib / dylib 路径、driver/codegen 边界 |
| Phase 5 | 已完成 | 最小 C ABI 闭环、header projection、真实 C host 集成、sidecar header |
| Phase 6 | 已完成 | same-file query / rename / completion / semantic tokens / LSP parity |
对这些阶段的正确理解是:
- 它们已经“能持续迭代”,不是“所有细节都已做完”
- 后续切片应该在这些边界之上扩容
- 任何需要推翻这些边界的提案,都必须先说明为什么现有设计已经失效
当前主线:Phase 7 并发、异步与 Rust 互操作
目标
- 把
async fn、await、spawn从“语法存在”推进到“可分析、可诊断、可逐步 lowering” - 把 runtime / executor / task-handle / hook ABI 的边界固定下来
- 在不放宽过头的前提下,建立可复现的 Rust 互操作路径
当前已落地基线
当前已经形成的 Phase 7 事实面:
Task[T]已作为显式 task-handle 类型面进入ql-resolve/ql-typeckql-analysis已暴露 runtime requirement truth surfaceql-runtime已提供最小Task/JoinHandle/Executor/InlineExecutor- runtime hook ABI skeleton 已存在,并被
ql-driver/ql-codegen-llvm共享消费 - backend 已支持最小 async body wrapper、frame scaffold、loadable
await(当前已覆盖 scalar /Task[T]/ 递归可加载 aggregate payload,以及由 tuple / fixed-array / non-generic struct 递归构成、并在内部继续携带Task[T]的 fixed-shape payload 子集)、task-handle-awarespawn - projected task-handle operand 已支持 tuple index / fixed-array literal index / struct field 只读投影路径;borrowck 现也已对 dynamic fixed-array index task-handle 打开两层 consume 精度:generic dynamic path 会保留 sibling-safe consume,而 same immutable stable index path(例如
index、slot.value)现也可精确识别为同一路径,因此await pending.tasks[index]/spawn pending.tasks[index]不再直接污染 sibling projection,await tasks[index]; await tasks[index]与await tasks[slot.value]; await tasks[slot.value]都会稳定报 definite use-after-move;跨具体元素的后续读取仍保持 maybe-moved - fixed-array literal index precision 现也会回收最小 immutable const alias / same-file
const/staticitem / same-file item alias:当let index = 0、let slot = Slot { value: 0 }、const INDEX: Int = 0、static INDEX: Int = 0、const SLOT: Slot = Slot { value: 0 }、static SLOT: Slot = Slot { value: 0 },或use SLOT as INDEX_ALIAS这类来源能在 borrowck / codegen 内保守折叠回 literal index 时,await tasks[index]; await tasks[0]、await tasks[slot.value]; await tasks[0]、await tasks[INDEX]; await tasks[0]、await tasks[SLOT.value]; await tasks[0]与await tasks[INDEX_ALIAS.value]; await tasks[0]都会走同一条 literal path overlap,而不是继续停留在 generic dynamic maybe-overlap - 同一条 literal/projection path 现也可通过最小 equality guard 在 dominated branch 内回收:当
if index == 0或if slot.value == 0这类条件把 stable dynamic source path 收窄到具体元素时,await tasks[index]; await tasks[0]会在分支内稳定报 definite use-after-move,而await tasks[index]; tasks[0] = worker(); await tasks[0]与对应的 projected 版本也可恢复通过,不再在 branch join 上停留为 maybe-moved;当前这条 guard-sensitive reinit 现也已进入async fn main的 user-facing program build matrix:directmain里的slot.value == 0projected path,以及经由 internal async helper body 进入的 directindex == 0path,都可在BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable下稳定构建 - 同一套 equality-guard refinement 现也已进入 deferred cleanup 的 HIR 分析:
defer if index == 0 { forward(tasks[index]) } else { ... }与 projectedslot.value版本现在会在 cleanup then-branch 内回收到tasks[0],同时也会保留外层index != 0/slot.value != 0路径的排除事实,因此tasks[0] = worker()后的 cleanup 不再误报 use-after-move;用户可见 build 面现已开放首个 cleanup lowering 子集:direct / call-backeddefer、由当前 shipped cleanup expr statement 顺序组成并允许 binding /_/ tuple destructuring / struct destructuring / fixed-array destructuring(叶子仍限 binding /_)最小letstatement 的 cleanup block、statement-sequenced cleanup guard / scrutinee block、statement-sequenced cleanup call-arg value block、statement-level local/projection assignment expr(当前限 ordinary local / param /selfplace family 下的 local/field/tuple-index/fixed-array-index roots),以及同一批 target path 的 cleanup assignment expr value(当前已覆盖 direct cleanup call arg 与 valued cleanup block tail)、带 body-localbreak/continue的 statement-levelwhile/loopcleanup block、fixed array / homogeneous tuple + binding /_/ tuple destructuring / struct destructuring / fixed-array destructuring(叶子仍限 binding /_)pattern 的 statement-levelforcleanup block(当前 iterable 已覆盖 direct root、same-fileconst/staticroot 及其 same-file alias、item-backed read-only projected root、direct call-root、same-file import-alias call-root,以及 nested call-root projected root,并额外接受能折叠回既有 literal/aggregate root 的if/ 最小 literalmatch根表达式)、async body 内 fixed array / homogeneous tuple iterable 的 statement-level cleanupfor awaitblock(当前 loop pattern 已覆盖 binding /_/ tuple destructuring / struct destructuring / fixed-array destructuring,叶子仍限 binding /_;根形态已覆盖 direct local root、same-file scalarconst/staticroot、same-file scalar item alias、scalar item-backed read-only projected root、same-file task-producingconst/staticroot、same-file task item alias root、projected task item root、direct block-valued / assignment-valued / runtimeif/match/ awaited direct root、direct question-mark root、read-only projected root、assignment-valued projected root、block-valued projected root、direct call-root、same-file import-alias call-root、nested call-root projected root、awaited projected root、runtimeif/matchaggregate projected root、transparent?wrapper 下的 projected root,以及 inline array/tuple task root)、bool-guard 驱动的 call-backedifcleanup branch、bool/int scrutinee + literal/path/wildcard/single-binding-catch-all arms + optional bool guard 的 cleanupmatchbranch,以及这些已开放 cleanup 子路径上的透明?wrapper;cleanupletvalue /ifcondition / call-arg scalar-value path 也会复用同一条 literal-source folding,因此同样接受这类 foldableif/ literalmatch根,而 cleanup callable / guard-call callee root 现也接受 runtimeif/matchtyped-value path 选出的 same-file function item / alias、function-item-backed callableconst/static/ alias,以及 closure-backed callableconst/static/ alias;更广义的 cleanup control flow 仍继续保守关闭,其中 cleanupfor await目前仍只开放 fixed-shape iterable 子集 - direct / projected / nested projected / same-file import-alias projected / same-file import-alias nested projected / control-flow selected projected / control-flow selected nested projected / same-file import-alias control-flow selected projected / same-file import-alias control-flow selected nested projected / call-root / same-file import-alias call-root / control-flow selected call-root / nested call-root projected / same-file import-alias nested call-root projected / control-flow selected nested call-root projected / same-file import-alias control-flow selected nested call-root projected 非 awaited tuple / struct / fixed-array cleanup
matchcatch-all 这轮也已从这段泛化描述里单独抽成公开回归:defer match (4, 5) { (left, right) if left < right => ... }、defer match cleanup_current { State { value } if value == 6 => ... }、defer match [4, 5, 6] { [first, middle, last] if middle == 5 => ... },以及defer match bundle.pair/bundle.current/bundle.values/tuple_env.outer.payload.values/state_env.outer.payload.current/array_env.outer.payload.values/cleanup_bundle_alias.pair/cleanup_bundle_alias.current/cleanup_bundle_alias.values/cleanup_tuple_alias.outer.payload.values/cleanup_state_alias.outer.payload.current/cleanup_array_alias.outer.payload.values/(match branch { true => tuple_left, false => tuple_right }).outer.payload.values/(if branch { state_left } else { state_right }).outer.payload.current/(match branch { true => array_left, false => array_right }).outer.payload.values/(match branch { true => cleanup_left_bundle_alias, false => cleanup_right_bundle_alias }).pair/(if branch { cleanup_left_bundle_alias } else { cleanup_right_bundle_alias }).current/(match branch { true => cleanup_left_bundle_alias, false => cleanup_right_bundle_alias }).values/(match branch { true => cleanup_left_tuple_alias, false => cleanup_right_tuple_alias }).outer.payload.values/(if branch { cleanup_left_state_alias } else { cleanup_right_state_alias }).outer.payload.current/(match branch { true => cleanup_left_array_alias, false => cleanup_right_array_alias }).outer.payload.values/(match branch { true => left, false => right }).pair/(if branch { left } else { right }).current/(match branch { true => left, false => right }).values/pair_value()/state_value()/values()/pair_alias()/state_alias()/values_alias()/(match branch { true => pair_value, false => alt_pair_value })()/(if branch { state_value } else { alt_state_value })()/(match branch { true => values, false => alt_values })()/tuple_env(1).payload.values/state_env(3).payload.current/deep_env(6).outer.payload.values/tuples(1).payload.values/states(3).payload.current/deep(6).outer.payload.values/(if ... { state_env } else { alt_state_env })(3).payload.current/(match ... { true => tuple_env, false => alt_tuple_env })(1).payload.values/(match ... { true => deep_env, false => alt_deep_env })(4).outer.payload.values/(if ... { states } else { alt_states })(3).payload.current/(match ... { true => tuples, false => alt_tuples })(1).payload.values/(match ... { true => deep, false => alt_deep })(4).outer.payload.values这类 projected-root / nested-projected-root / same-file-import-alias-projected / same-file-import-alias-nested-projected / control-flow-selected-projected / control-flow-selected-nested-projected / same-file-import-alias-control-flow-selected-projected / same-file-import-alias-control-flow-selected-nested-projected / call-root / import-alias-call-root / control-flow-selected-call-root / nested-call-root-projected / import-alias-nested-call-root-projected / control-flow-selected-nested-call-root-projected / import-alias-control-flow-selected-nested-call-root-projected aggregate scrutinee,现在都会稳定复用同一条 cleanup catch-all lowering,而不再只靠“loadable 非标量 scrutinee + catch-all pattern”的抽象文案兜底 - cleanup value path 现也开始接受 runtime
ifvalue:当前 direct cleanup call arg 已可通过if cond { ... } else { ... }进入 shared cleanup value lowering,不再只限 literal-source foldedif - cleanup value path 现也开始接受 runtime
matchvalue:当前 direct cleanup call arg 已可通过 bool/int scrutinee + 既有 cleanup-match arm 子集进入 shared cleanup value lowering,不再只限 literal-source foldedmatch - cleanup value path 现也开始接受最小 runtime
awaitvalue:当前 async body 内 direct cleanup call arg 已可通过await task进入 shared cleanup value lowering,不再只限 task-handle call result 被直接忽略的 expr-statement 形态 - cleanup value path 现也开始接受最小 runtime
spawnvalue:当前 async body 内 direct cleanup call arg 已可通过spawn worker(...)/spawn task进入 shared cleanup value lowering,不再只限先脱离 cleanup 再绑定局部的 task-handle 提交路径 - cleanup bool guard path 现也开始接受最小 runtime
awaitvalue:当前 async body 内defer if await ready()、cleanupmatchguardtrue if await check(...)、defer if await (if/match选出的 same-file async function item / alias 与 async callableconst/static/ alias)(...)、defer if helper_alias(..., await ...)/defer if State { value: (await ...).value }.value == ...这类 awaited helper / inline guard,以及defer if wrap(await ...).slot.value == .../ cleanupmatchguard 里的[wrap(await ...).slot.value, 0][offset(...)]这类 awaited nested runtime projection / inline-combo guard,都已可进入 shared cleanup guard lowering - cleanup scrutinee path 现也开始接受最小 runtime
awaitvalue:当前 async body 内 bool/int scrutinee 的defer match await ...、defer match (await ...).value { ... }、defer match helper_alias(..., await ...)、defer match State { value: (await ...).value }.value { ... }这类 awaited helper / inline scrutinee,以及defer match wrap(await ...).slot.value { ... }/defer match [wrap(await ...).slot.value, 0][offset(...)] { ... }这类 awaited nested runtime projection / inline-combo scrutinee,都已可进入 shared cleanup scrutinee lowering;上一轮已补上 loadable aggregate scrutinee + wildcard/single-binding catch-all arm 子集,因此defer match await ... { current => ... }可直接承载 awaited struct / tuple / fixed-array scrutinee;本轮继续把同一路径推进到 tuple / struct destructuring catch-all,因此 cleanup body 与 valued cleanupmatch现在都可直接写(left, right) => .../State { slot: Slot { value } } => ...,其中 awaited callee root 同样可来自 runtimeif/match选出的 same-file async function item / alias 与 async callableconst/static/ alias - cleanup control-flow 现也开始接受首个
for awaitlowering 子集:当前 async body 内的 cleanup block 已开放 fixed array / homogeneous tuple iterable;普通元素会直接逐项绑定,Task[...]元素会复用既有task-await/task-result-release路径做逐项 auto-await,并继续支持 body-localbreak/continue;当前 loop pattern 也已覆盖 binding /_/ tuple destructuring / struct destructuring / fixed-array destructuring(叶子仍限 binding /_);当前 public regression 也已锁定 same-file scalarconst/staticroot、same-file scalar item alias、same-file task-producingconst/staticroot、same-file task item alias root、projected task item root、scalar item-backed read-only projected root、direct question-mark root、read-only projected root、assignment-valued projected root、block-valued projected root、direct call-root、awaited projected root、runtimeif/matchaggregate projected root、transparent?wrapper 下的 projected root,以及 inline array/tuple task root - cleanup aggregate staging 现也补上了与上述 async value path 对齐的递归 lowering:tuple / array / struct literal 在 cleanup
let、valued block 和 projected-root materialization 中不再借道 guard-only loadable recursion,而是会递归复用 cleanup value path;因此(await task_env(1)).payload.tasks这类 awaited projected task-array 现在可以先装进 cleanup struct literal 字段,再由后续 cleanupfor await消费 - 普通
?lowering 现已走通最小后端路径:match-wrappedhelper()?、cleanup-adjacentreturn helper()?、cleanup-internaldefer helper()?与普通 return path 都不再因为Rvalue::Question本身被ql-codegen-llvm拦截;当前 remaining blocker 已前移到更宽 cleanup control flow,而不是 transparent question-mark path - 普通 assignment expr 的最小后端 value path 现也已接通:沿现有
StatementKind::Assign的 place/type/store 规则,ordinary build surface 现在已接受同一批 mutable local / tuple-index / struct-field / fixed-array literal-index target path 的 assignment expr value,并已锁定 direct call arg 与 valued block tail 两条公开回归;更宽 target family 与 broader expression elaboration 仍继续保守推进 - 同一批 guard assignment expr value 现也已继续接进 guard 路径:除 shipped cleanup
ifcondition 的 bool assignment expr 外,ordinarymatchguard / cleanup guard-call 现也接受同一批 ordinary local / param /selfroot 的 loadable assignment expr call arg;更宽 guard-folding 精化仍继续保持保守 - guard value path 现也开始接受 runtime
ifvalue:当前 ordinarymatchguard 的 loadable guard-call arg 已可通过if cond { ... } else { ... }进入 shared typed guard-value lowering,不再只限 literal-source foldedif - guard value path 现也开始接受 runtime
matchvalue:当前 ordinarymatchguard 的 loadable guard-call arg 已可通过 bool/int scrutinee + 既有 guard-match arm 子集进入 shared typed guard-value lowering,不再只限 literal-source foldedmatch - guard scalar/value path 现也开始接受 runtime
awaitvalue:当前 ordinarymatchguard 的 awaited scalar comparison、awaited aggregate projection comparison、awaited aggregate guard-call arg、awaited call-backed aggregate guard arg、awaited import-alias helper arg、awaited nested call-root runtime projection / 最小 inline-combo,以及 awaited inline aggregate arg / inline projection-root,都已可通过 runtimeif/match选出的 same-file async function item / alias 与 async callableconst/static/ alias direct callee root 进入 shared guard-value lowering - ordinary
matchscrutinee path 现也开始接受最小 runtimeawaitvalue:当前 ordinarymatch await ...的 direct awaited scrutinee、ordinarymatch await ...的 awaited aggregate catch-all scrutinee(现已从 single-binding 扩到_/ single binding / tuple destructuring / struct destructuring / fixed-array destructuring,覆盖 struct / tuple / fixed-array aggregate,并已锁定match await ... { [first, _, last] => ... }这类 fixed-array catch-all)、ordinarymatch (await ...).value这类 direct awaited projected scrutinee、ordinarymatch的 awaited helper / inline scrutinee,以及 awaited nested call-root runtime projection / inline-combo scrutinee,都已可通过 runtimeif/match选出的 same-file async function item / alias 与 async callableconst/static/ alias direct callee root 进入 shared scrutinee lowering - ordinary / cleanup direct awaited call-root aggregate
matchcatch-all 这轮也已从这段泛化描述里单独抽成公开回归:match await pair_value(1) { (left, right) if left < right => ... }、match await state_value(3) { State { value } if value == 3 => ... }、match await values(4) { [first, middle, last] if middle == 5 => ... },以及对应的defer match await pair_value(4) { ... }、defer match await state_value(6) { ... }与defer match await values(7) { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 direct awaited call-root aggregate scrutinee 继续只靠“match await ...aggregate catch-all”这类泛化描述侧写 - ordinary / cleanup same-file import-alias awaited call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match await pair_alias(1) { (left, right) if left < right => ... }、match await state_const_alias(3) { State { value } if value == 3 => ... }、match await values_alias(4) { [first, middle, last] if middle == 5 => ... },以及对应的defer match await pair_const_alias(4) { ... }、defer match await state_alias(6) { ... }与defer match await values_const_alias(7) { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias awaited call-root aggregate scrutinee 继续只靠 direct awaited call-root aggregate catch-all 与 import-alias awaited projected aggregate 文案侧写 - ordinary / cleanup control-flow selected awaited call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match await (if branch { pair_value } else { PAIR_VALUE })(1) { (left, right) if left < right => ... }、match await (match branch { true => STATE_VALUE, false => state_value })(3) { State { value } if value == 3 => ... }、match await (if branch { values } else { VALUES })(4) { [first, middle, last] if middle == 5 => ... },以及对应的defer match await (match branch { true => PAIR_VALUE, false => pair_value })(4) { ... }、defer match await (if branch { state_value } else { STATE_VALUE })(6) { ... }与defer match await (match branch { true => VALUES, false => values })(7) { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow selected awaited call-root aggregate scrutinee 继续只靠 direct awaited call-root aggregate catch-all 与 control-flow awaited projected aggregate 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected awaited call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match await (if branch { pair_alias } else { pair_const_alias })(1) { (left, right) if left < right => ... }、match await (match branch { true => state_const_alias, false => state_alias })(3) { State { value } if value == 3 => ... }、match await (if branch { values_alias } else { values_const_alias })(4) { [first, middle, last] if middle == 5 => ... },以及对应的defer match await (match branch { true => pair_const_alias, false => pair_alias })(4) { ... }、defer match await (if branch { state_alias } else { state_const_alias })(6) { ... }与defer match await (match branch { true => values_const_alias, false => values_alias })(7) { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias control-flow selected awaited call-root aggregate scrutinee 继续只靠 import-alias awaited call-root aggregate catch-all 与 control-flow awaited call-root aggregate 文案侧写 - ordinary / cleanup direct awaited projected aggregate
matchcatch-all 这轮也已从这段泛化描述里单独抽成公开回归:match (await tuple_env(1)).payload.values { (left, right) if left < right => ... }、match (await state_env(3)).payload.current { State { value } if value == 3 => ... }、match (await array_env(4)).payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await tuple_env(1)).payload.values { ... }、defer match (await state_env(3)).payload.current { ... }与defer match (await array_env(4)).payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 direct awaited projected aggregate scrutinee 继续只靠“match (await ...).value+ awaited aggregate catch-all”两段分散文案侧写 - ordinary / cleanup same-file import-alias awaited projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await tuple_alias(1)).payload.values { (left, right) if left < right => ... }、match (await state_const_alias(3)).payload.current { State { value } if value == 3 => ... }、match (await array_alias(4)).payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await tuple_const_alias(1)).payload.values { ... }、defer match (await state_alias(3)).payload.current { ... }与defer match (await array_const_alias(4)).payload.values { ... }形态,现在也都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias awaited projected aggregate scrutinee 继续只靠 direct awaited projected aggregate catch-all 与 generic awaited alias root 文案侧写 - ordinary / cleanup control-flow selected awaited projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await (if ... { tuple_env } else { TUPLE_ENV })(1)).payload.values { (left, right) if left < right => ... }、match (await (match ... { true => STATE_ENV, false => state_env })(3)).payload.current { State { value } if value == 3 => ... }、match (await (if ... { array_env } else { ARRAY_ENV })(4)).payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await (match ... { true => TUPLE_ENV, false => tuple_env })(1)).payload.values { ... }、defer match (await (if ... { state_env } else { STATE_ENV })(3)).payload.current { ... }与defer match (await (match ... { true => ARRAY_ENV, false => array_env })(4)).payload.values { ... }形态,现在也都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow selected awaited projected aggregate scrutinee 继续只靠 direct awaited projected aggregate catch-all 与 generic awaited control-flow root 文案侧写 - ordinary / cleanup direct awaited nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await tuple_env(1)).outer.payload.values { (left, right) if left < right => ... }、match (await state_env(3)).outer.payload.current { State { value } if value == 3 => ... }、match (await array_env(4)).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await tuple_env(1)).outer.payload.values { ... }、defer match (await state_env(3)).outer.payload.current { ... }与defer match (await array_env(4)).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 direct awaited nested projected aggregate scrutinee 继续只靠 direct awaited projected aggregate catch-all 与 generic awaited nested projection 文案侧写 - ordinary / cleanup same-file import-alias awaited nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await tuple_alias(1)).outer.payload.values { (left, right) if left < right => ... }、match (await state_const_alias(3)).outer.payload.current { State { value } if value == 3 => ... }、match (await array_alias(4)).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await tuple_const_alias(1)).outer.payload.values { ... }、defer match (await state_alias(3)).outer.payload.current { ... }与defer match (await array_const_alias(4)).outer.payload.values { ... }形态,现在也都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias awaited nested projected aggregate scrutinee 继续只靠 direct awaited nested projected aggregate catch-all 与 generic awaited alias root 文案侧写 - ordinary / cleanup control-flow selected awaited nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await (if ... { tuple_env } else { TUPLE_ENV })(1)).outer.payload.values { (left, right) if left < right => ... }、match (await (match ... { true => STATE_ENV, false => state_env })(3)).outer.payload.current { State { value } if value == 3 => ... }、match (await (if ... { array_env } else { ARRAY_ENV })(4)).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await (match ... { true => TUPLE_ENV, false => tuple_env })(1)).outer.payload.values { ... }、defer match (await (if ... { state_env } else { STATE_ENV })(3)).outer.payload.current { ... }与defer match (await (match ... { true => ARRAY_ENV, false => array_env })(4)).outer.payload.values { ... }形态,现在也都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow selected awaited nested projected aggregate scrutinee 继续只靠 direct awaited nested projected aggregate catch-all 与 generic awaited control-flow root 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected awaited projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await (if ... { tuple_alias } else { tuple_const_alias })(1)).payload.values { (left, right) if left < right => ... }、match (await (match ... { true => state_const_alias, false => state_alias })(3)).payload.current { State { value } if value == 3 => ... }、match (await (if ... { array_alias } else { array_const_alias })(4)).payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await (match ... { true => tuple_const_alias, false => tuple_alias })(1)).payload.values { ... }、defer match (await (if ... { state_alias } else { state_const_alias })(3)).payload.current { ... }与defer match (await (match ... { true => array_const_alias, false => array_alias })(4)).payload.values { ... }形态,现在也都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias control-flow selected awaited projected aggregate scrutinee 继续只靠 direct awaited projected aggregate catch-all 与 generic awaited control-flow root 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected awaited nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (await (if ... { tuple_alias } else { tuple_const_alias })(1)).outer.payload.values { (left, right) if left < right => ... }、match (await (match ... { true => state_const_alias, false => state_alias })(3)).outer.payload.current { State { value } if value == 3 => ... }、match (await (if ... { array_alias } else { array_const_alias })(4)).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (await (match ... { true => tuple_const_alias, false => tuple_alias })(1)).outer.payload.values { ... }、defer match (await (if ... { state_alias } else { state_const_alias })(3)).outer.payload.current { ... }与defer match (await (match ... { true => array_const_alias, false => array_alias })(4)).outer.payload.values { ... }形态,现在也都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias control-flow selected awaited nested projected aggregate scrutinee 继续只靠 direct awaited nested projected aggregate catch-all 与 generic awaited control-flow root 文案侧写 - ordinary direct / projected / call-root / same-file import-alias call-root / nested call-root projected / same-file import-alias nested call-root projected / control-flow selected nested call-root projected / same-file import-alias control-flow selected nested call-root projected loadable
matchcatch-all 这轮也已补上 import-alias control-flow selected nested call-root aggregate 的独立公开锁定:除match (1, 2) { (left, right) if left < right => ... }、match current { State { value } if value == 3 => ... }、match [1, 2, 3] { [first, _, last] if first < last => ... }与match bundle.pair/bundle.current/bundle.values这类 projected aggregate scrutinee、match pair_value()/state_value()/values()这类 direct call-root aggregate scrutinee、match pair_alias()/state_alias()/values_alias()这类 same-file import-alias call-root aggregate scrutinee、match tuple_env(1).payload.values/state_env(3).payload.current/deep_env(6).outer.payload.values这类 nested call-root projected aggregate scrutinee、match tuples(1).payload.values/states(3).payload.current/deep(6).outer.payload.values这类 same-file import-alias nested call-root projected aggregate scrutinee,以及match (if ... { tuple_env } else { alt_tuple_env })(1).payload.values/match (match ... { true => state_env, false => alt_state_env })(3).payload.current/match (if ... { deep_env } else { alt_deep_env })(4).outer.payload.values这类 control-flow selected nested call-root projected aggregate scrutinee外,match (if ... { tuples } else { alt_tuples })(1).payload.values/match (match ... { true => states, false => alt_states })(3).payload.current/match (if ... { deep } else { alt_deep })(4).outer.payload.values这类 same-file import-alias control-flow selected nested call-root projected aggregate scrutinee 现在也都已由单独的 fixture 与 driver/CLI 回归覆盖,避免 ordinary aggregate catch-all 继续只靠 direct root、projected root、call-root、import-alias-call-root、nested-call-root-projected、import-alias-nested-call-root-projected、control-flow-selected-nested-call-root-projected、awaited family 或 generic current-loadable 文案侧写 - ordinary / cleanup transparent question-wrapped projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (bundle_value()?).pair { (left, right) if left < right => ... }、match (bundle_value()?).current { State { value } if value == 3 => ... }与match (bundle_value()?).values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (bundle_value()?).pair { ... }、defer match (bundle_value()?).current { ... }与defer match (bundle_value()?).values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 question-wrapped projected aggregate scrutinee 继续只靠 projected aggregate 文案、match+?最小样例与 cleanupforprojected question-root 局部样例侧写 - ordinary / cleanup same-file import-alias transparent question-wrapped projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (bundle_alias()?).pair { (left, right) if left < right => ... }、match (bundle_alias()?).current { State { value } if value == 3 => ... }、match (bundle_alias()?).values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (cleanup_bundle_alias()?).pair { ... }、defer match (cleanup_bundle_alias()?).current { ... }与defer match (cleanup_bundle_alias()?).values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias question-wrapped projected aggregate scrutinee 继续只靠 direct question-wrapped projected 文案、import-alias projected 文案与 cleanupforprojected question-root 局部样例侧写 - ordinary / cleanup control-flow selected transparent question-wrapped projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match ((if branch { bundle_value } else { alt_bundle_value })()?).pair { (left, right) if left < right => ... }、match ((match branch { true => bundle_value, false => alt_bundle_value })()?).current { State { value } if value == 3 => ... }与match ((if branch { bundle_value } else { alt_bundle_value })()?).values { [first, middle, last] if middle == 5 => ... },以及对应的defer match ((match branch { true => bundle_value, false => alt_bundle_value })()?).pair { ... }、defer match ((if branch { bundle_value } else { alt_bundle_value })()?).current { ... }与defer match ((match branch { true => bundle_value, false => alt_bundle_value })()?).values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow question-wrapped projected aggregate scrutinee 继续只靠 direct question-wrapped projected 文案、control-flow projected 文案与 question-wrapped call-root 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected transparent question-wrapped projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match ((if branch { bundle_alias } else { alt_bundle_alias })()?).pair { (left, right) if left < right => ... }、match ((match branch { true => bundle_alias, false => alt_bundle_alias })()?).current { State { value } if value == 3 => ... }与match ((if branch { bundle_alias } else { alt_bundle_alias })()?).values { [first, middle, last] if middle == 5 => ... },以及对应的defer match ((match branch { true => cleanup_bundle_alias, false => cleanup_alt_bundle_alias })()?).pair { ... }、defer match ((if branch { cleanup_bundle_alias } else { cleanup_alt_bundle_alias })()?).current { ... }与defer match ((match branch { true => cleanup_bundle_alias, false => cleanup_alt_bundle_alias })()?).values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias control-flow question-wrapped projected aggregate scrutinee 继续只靠 import-alias question-wrapped projected 文案、control-flow question-wrapped projected 文案与 import-alias control-flow projected 文案侧写 - ordinary / cleanup transparent question-wrapped nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (tuple_env?).outer.payload.values { (left, right) if left < right => ... }、match (state_env?).outer.payload.current { State { value } if value == 3 => ... }与match (array_env?).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (tuple_env?).outer.payload.values { ... }、defer match (state_env?).outer.payload.current { ... }与defer match (array_env?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 question-wrapped nested projected aggregate scrutinee 继续只靠 direct nested projected 文案、question-wrapped projected 文案与 question-wrapped nested call-root 文案侧写 - ordinary / cleanup same-file import-alias transparent question-wrapped nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (tuple_alias?).outer.payload.values { (left, right) if left < right => ... }、match (state_alias?).outer.payload.current { State { value } if value == 3 => ... }与match (array_alias?).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match (cleanup_tuple_alias?).outer.payload.values { ... }、defer match (cleanup_state_alias?).outer.payload.current { ... }与defer match (cleanup_array_alias?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias question-wrapped nested projected aggregate scrutinee 继续只靠 direct question-wrapped nested projected 文案、import-alias nested projected 文案与 import-alias question-wrapped nested call-root 文案侧写 - ordinary / cleanup control-flow selected transparent question-wrapped nested projected aggregate
matchcatch-all 这轮也已补上独立公开锁定:match ((if branch { tuple_left } else { tuple_right })?).outer.payload.values { (left, right) if left < right => ... }、match ((match branch { true => state_left, false => state_right })?).outer.payload.current { State { value } if value == 3 => ... }与match ((if branch { array_left } else { array_right })?).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match ((match branch { true => tuple_left, false => tuple_right })?).outer.payload.values { ... }、defer match ((if branch { state_left } else { state_right })?).outer.payload.current { ... }与defer match ((match branch { true => array_left, false => array_right })?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow question-wrapped nested projected aggregate scrutinee 继续只靠 direct question-wrapped nested projected 文案、control-flow nested projected 文案与 control-flow question-wrapped nested call-root 文案侧写 - ordinary / cleanup control-flow selected call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (if branch { pair_value } else { alt_pair_value })() { (left, right) if left < right => ... }、match (match branch { true => state_value, false => alt_state_value })() { State { value } if value == 3 => ... }、match (if branch { values } else { alt_values })() { [first, middle, last] if middle == 5 => ... },以及对应的defer match (match branch { true => pair_value, false => alt_pair_value })() { ... }、defer match (if branch { state_value } else { alt_state_value })() { ... }与defer match (match branch { true => values, false => alt_values })() { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow selected call-root aggregate scrutinee 继续只靠 direct call-root aggregate catch-all 与更一般的 callable control-flow root 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (if branch { pair_alias } else { alt_pair_alias })() { (left, right) if left < right => ... }、match (match branch { true => state_alias, false => alt_state_alias })() { State { value } if value == 3 => ... }、match (if branch { values_alias } else { alt_values_alias })() { [first, middle, last] if middle == 5 => ... },以及对应的defer match (match branch { true => pair_alias, false => alt_pair_alias })() { ... }、defer match (if branch { state_alias } else { alt_state_alias })() { ... }与defer match (match branch { true => values_alias, false => alt_values_alias })() { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 same-file import-alias control-flow selected call-root aggregate scrutinee 继续只靠 import-alias call-root aggregate catch-all 与更一般的 callable control-flow root 文案侧写 - ordinary / cleanup transparent question-wrapped call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match pair_value()? { (left, right) if left < right => ... }、match state_value()? { State { value } if value == 3 => ... }、match values()? { [first, middle, last] if middle == 5 => ... },以及对应的defer match pair_value()? { ... }、defer match state_value()? { ... }与defer match values()? { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 question-wrapped call-root aggregate scrutinee 继续只靠match+?最小标量样例与既有 call-root aggregate catch-all 文案侧写 - ordinary / cleanup same-file import-alias transparent question-wrapped call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match pair_alias()? { (left, right) if left < right => ... }、match state_alias()? { State { value } if value == 3 => ... }、match values_alias()? { [first, middle, last] if middle == 5 => ... },以及对应的defer match pair_alias()? { ... }、defer match state_alias()? { ... }与defer match values_alias()? { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias question-wrapped call-root aggregate scrutinee 继续只靠 direct question-wrapped call-root aggregate 文案与既有 import-alias call-root aggregate 文案侧写 - ordinary / cleanup control-flow selected transparent question-wrapped call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (if branch { pair_value } else { alt_pair_value })()? { (left, right) if left < right => ... }、match (match branch { true => state_value, false => alt_state_value })()? { State { value } if value == 3 => ... }、match (if branch { values } else { alt_values })()? { [first, middle, last] if middle == 5 => ... },以及对应的defer match (match branch { true => pair_value, false => alt_pair_value })()? { ... }、defer match (if branch { state_value } else { alt_state_value })()? { ... }与defer match (match branch { true => values, false => alt_values })()? { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow question-wrapped call-root aggregate scrutinee 继续只靠 direct question-wrapped call-root aggregate 文案与既有 control-flow call-root aggregate 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected transparent question-wrapped call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (if branch { pair_alias } else { alt_pair_alias })()? { (left, right) if left < right => ... }、match (match branch { true => state_alias, false => alt_state_alias })()? { State { value } if value == 3 => ... }、match (if branch { values_alias } else { alt_values_alias })()? { [first, middle, last] if middle == 5 => ... },以及对应的defer match (match branch { true => pair_alias, false => alt_pair_alias })()? { ... }、defer match (if branch { state_alias } else { alt_state_alias })()? { ... }与defer match (match branch { true => values_alias, false => alt_values_alias })()? { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias control-flow question-wrapped call-root aggregate scrutinee 继续只靠 import-alias question-wrapped call-root 文案与既有 import-alias control-flow call-root 文案侧写 - ordinary / cleanup transparent question-wrapped nested call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (tuple_env(1)?).payload.values { (left, right) if left < right => ... }、match (state_env(3)?).payload.current { State { value } if value == 3 => ... }、match (array_env(4)?).payload.values { [first, middle, last] if middle == 5 => ... }与match (deep_env(6)?).outer.payload.values { [first, middle, last] if middle == 7 => ... },以及对应的defer match (tuple_env(1)?).payload.values { ... }、defer match (state_env(3)?).payload.current { ... }、defer match (array_env(4)?).payload.values { ... }与defer match (deep_env(6)?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 question-wrapped nested call-root aggregate scrutinee 继续只靠 direct question-wrapped call-root 文案、既有 nested call-root aggregate 文案与 projected question-root 局部样例侧写 - ordinary / cleanup same-file import-alias transparent question-wrapped nested call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match (tuples(1)?).payload.values { (left, right) if left < right => ... }、match (states(3)?).payload.current { State { value } if value == 3 => ... }、match (arrays(4)?).payload.values { [first, middle, last] if middle == 5 => ... }与match (deep(6)?).outer.payload.values { [first, middle, last] if middle == 7 => ... },以及对应的defer match (tuples(1)?).payload.values { ... }、defer match (states(3)?).payload.current { ... }、defer match (arrays(4)?).payload.values { ... }与defer match (deep(6)?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias question-wrapped nested call-root aggregate scrutinee 继续只靠 direct question-wrapped nested call-root 文案与既有 import-alias nested call-root 文案侧写 - ordinary / cleanup control-flow selected transparent question-wrapped nested call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match ((if true { tuple_env } else { alt_tuple_env })(1)?).payload.values { (left, right) if left < right => ... }、match ((match true { true => state_env, false => alt_state_env })(3)?).payload.current { State { value } if value == 3 => ... }与match ((if true { deep_env } else { alt_deep_env })(4)?).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match ((match true { true => tuple_env, false => alt_tuple_env })(1)?).payload.values { ... }、defer match ((if true { state_env } else { alt_state_env })(3)?).payload.current { ... }与defer match ((match true { true => deep_env, false => alt_deep_env })(4)?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 control-flow question-wrapped nested call-root aggregate scrutinee 继续只靠 direct question-wrapped nested call-root 文案与既有 control-flow nested call-root 文案侧写 - ordinary / cleanup same-file import-alias control-flow selected transparent question-wrapped nested call-root aggregate
matchcatch-all 这轮也已补上独立公开锁定:match ((if true { tuples } else { alt_tuples })(1)?).payload.values { (left, right) if left < right => ... }、match ((match true { true => states, false => alt_states })(3)?).payload.current { State { value } if value == 3 => ... }与match ((if true { deep } else { alt_deep })(4)?).outer.payload.values { [first, middle, last] if middle == 5 => ... },以及对应的defer match ((match true { true => tuples, false => alt_tuples })(1)?).payload.values { ... }、defer match ((if true { states } else { alt_states })(3)?).payload.current { ... }与defer match ((match true { true => deep, false => alt_deep })(4)?).outer.payload.values { ... }形态,现在都已由独立的 fixture 与 driver/CLI 回归覆盖,避免 import-alias control-flow question-wrapped nested call-root aggregate scrutinee 继续只靠 import-alias question-wrapped nested call-root 文案与既有 import-alias control-flow nested call-root 文案侧写 - guard callable callee root 现也开始接受 runtime
if/matchvalue:当前 ordinarymatchguard 的 indirect guard call 已可通过 same-file function item / alias、function-item-backed callableconst/static/ alias,以及 closure-backed callableconst/static/ alias 选出的 callable typed-value path 进入 shared guard-value lowering,不再只限 direct root 或 literal-source folded callee - sync callable value 已开放当前最小可用子集:same-file sync function item、same-file
use ... as ...function alias、transparently resolve 到 same-file sync function item 的 callableconst/static及其 same-file alias,现在都可在 ordinary call 中 direct call,或先绑定到 local 后再通过 positional indirect call 进入现有 LLVM build surface;non-capturing sync closure-backed callableconst/static及其 same-file alias,本轮也已接入 ordinary positional indirect-call 的最小用户面;let/var也已支持 statement-level 显式类型标注,因此let run: (Int) -> Int = (value) => value + 1这类 local callable annotation 现也已进入同一条用户可见 build 路径;non-capturing sync closure value 现也已接入同一条 ordinary positional indirect-call 路径,除 zero-arg regression、显式 typed closure parameter 子集、statement-level local callable annotation 子集,与 call-site positional argument 反推参数类型的 parameterized local / immutable-alias 子集外,当前 shipped cleanup / guard-call 子路径也已显式锁定 direct local non-capturing closure 的最小公开回归;capturing sync closure value 则已继续开放到 ordinary local/same-target call roots、ordinary local binding root 及其后续 local alias chain 调用、ordinary control-flow assignment-valued direct/binding/alias-chain root、local alias cleanup callee、local alias cleanup guard-call、assignment-valued cleanup callee / guard-call root、cleanup block 内局部 alias 的 direct call / guard-call(现含 statement-sequenced local mutable alias same-target reassign、statement-sequenced cleanup block 内局部 mutable alias 的 different-target reassign、assignment-valued same-target binding、control-flow 收敛到 same-target assignment-valued root 的 binding,以及 control-flow 分支内的 block-local alias tail binding;同类 direct cleanup callee / cleanup guard-call root 现在也已接通,包含 block-local different-target mutable alias direct root),与 ordinarymatchguard-call 的首个受控子集(现含 direct callee root、先绑定到 ordinary local 后再调用的 control-flow-selected root、block-local assignment-valued / control-flow-assignment-valued binding root,以及 different-closure control-flow 下的 block-local alias tail / block binding / local alias chain callee root);cleanupif/matchcontrol-flow 现在也继续接受分支内 same-target assignment-valued cleanup callee / guard-call root 的收敛形态;same-file async function item / alias,以及 transparently resolve 到 same-file async function item 的 callableconst/static/ same-file alias,现也已接入async fn内 ordinary direct call 或 ordinary local indirect-call +await的最小可用子集;当前 ordinarymatchguard、call-backed cleanupdefer与 cleanup guard-call 的最小间接调用路径,除 function-item-backed callable 值外,也已显式锁定 direct closure-backed callableconstguard + closure-backed callablestaticcleanup 的公开回归;更广义的 callable value lowering 仍继续保守关闭,主要剩余 other cleanup escape flow,以及 cleanup 内更广义的 async control-flow - same immutable source alias 现也会在 dynamic task-handle index 上做最小归一化:当
let alias = index或let slot = Slot { value: index }这类不可变别名最终仍指向同一个稳定 source path 时,tasks[alias]/tasks[slot.value]会和tasks[index]归到同一条 stable dynamic path,因此跨别名 reuse / reinit 不再额外退化成 maybe-overlap;同一条稳定化逻辑现也可递归组合到 composed dynamic source path,例如let slots = [row, row]; await tasks[slots[row]]; tasks[slots[row]] = worker(); await tasks[slots[row]]不再被迫退化成 generic maybe-overlap,而当这类 composed source path 再经过 immutable alias(例如let alias = slots; await tasks[alias[row]]; await tasks[slots[row]])时,也会继续落回同一条 stable dynamic path - task-handle root canonicalization 现也已覆盖普通 alias read,而不只是在
await/spawn/ helper task-handle consume 时生效:let alias = task; await task; let pair = (alias, worker())这类“把已移动句柄重新包装进 aggregate”的路径现在会在 alias read 处稳定报 source-root use-after-move,而task = worker()/pending.tasks[index] = worker()这类 source-local/source-path reinit 后,let pair = (alias, worker())/let pair = (alias[index], worker())也会恢复通过;同一条 root canonicalization 仍已覆盖 direct、dynamic root 与 projected root 形态 - 非
Task[...]元素的 dynamic array assignment 已开放并在 driver/CLI 两层锁定;Task[...]动态数组索引写入现也已从单纯 write-only 扩到“generic dynamic 保守 reinit + same immutable stable index path precise reinit”子集,但仍不把任意 dynamic index 误当成 fully precise reinit - generic dynamic
Task[...]array assignment 与 sibling-safe dynamic consume/spawn 现也已显式锁进 user-facing build matrix:staticlib下的 async helper 与BuildEmit::Executable下的async fn main()都已有 codegen / driver / CLI 定向回归,不再只依赖内部单测证明这条保守子集“理论上可用”;same immutable stable index path 的 projected-root reinit(例如pending.tasks[slot.value])与 const-backed projected-root literal reuse(例如pending.tasks[INDEX])也已补进这条用户可见回归面 - projected-root dynamic task-handle reinit 的 current program subset 现也已补齐 emit parity:
async fn main下的await pending.tasks[slot.value]; pending.tasks[slot.value] = worker(...); await pending.tasks[slot.value],以及 const-backed projected-root literal reuseawait pending.tasks[INDEX]; pending.tasks[0] = worker(...); await pending.tasks[INDEX],都已进入BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable的 public regression matrix,不再只有exe端到端用例而缺少llvm-ir/object用户面锁定 - projected-root alias-root canonicalization 的 current program subset 现也已补齐到真实运行闭环:
async fn main下的let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = worker(...); let second = await alias[slot.value]现在也已进入BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable的 public regression matrix,并修复了此前“可构建但真实 executable 读取 stale alias copy 导致崩溃”的 backend 缺口 - const-backed projected-root alias-root canonicalization 的 current program subset 现也已进入同一条 public regression matrix:
async fn main下的let alias = pending.tasks; let first = await alias[INDEX]; pending.tasks[0] = worker(...); let second = await alias[INDEX]现也已覆盖BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable,说明 same-file const item 驱动的 literal reuse 在 alias-root projected-root 形态下不再只停留于“理论上复用现有 lowering” - static/use-alias-backed projected-root alias-root canonicalization 的 current program subset 本轮也已补进 public regression matrix:
async fn main下的use SLOT as INDEX_ALIAS; let alias = pending.tasks; let first = await alias[INDEX_ALIAS.value]; pending.tasks[0] = worker(...); let second = await alias[INDEX_ALIAS.value]现已进入 driverBuildEmit::Object与 CLIobject/executablepass matrix,说明 same-filestaticitem 与 same-fileuse ... as ...alias 驱动的 projected-root literal/stable-path reuse 不再只停留在 borrowck/staticlib内部回归。 - guard-refined static/use-alias-backed projected-root alias-root canonicalization 的 current program subset 本轮也已补进 driver/CLI public regression matrix:
async fn main下的use SLOT as INDEX_ALIAS; let alias = pending.tasks; if INDEX_ALIAS.value == 0 { let first = await alias[INDEX_ALIAS.value]; pending.tasks[0] = worker(...) } let second = await alias[0]现已进入 driverBuildEmit::Object与 CLIllvm-ir/object/executablepass matrix,说明 same-filestaticitem、same-fileuse ... as ...alias 与 equality-guard refinement 的三者组合也能稳定复用当前 projected-root literal/projection path;前一轮已把 direct path 提升到真实 executable 示例ramdon_tests/async_program_surface_examples/73_async_main_aliased_guard_refined_static_alias_backed_projected_root.ql,由crates/ql-cli/tests/executable_examples.rs锁定退出码35;上一轮又继续把同一路径推进到 nested aggregate submit 形态,新增ramdon_tests/async_program_surface_examples/74_async_main_aliased_guard_refined_static_alias_backed_nested_repackage_spawn.ql,锁定退出码42;上一轮再把同一路径推进到 helper-forwarded nested fixed-array submit 形态,新增ramdon_tests/async_program_surface_examples/75_async_main_aliased_guard_refined_static_alias_backed_forwarded_nested_array_repackage_spawn.ql,锁定退出码58;随后继续把同一路径推进到 alias-sourced composed dynamic + helper-forwarded nested fixed-array submit 形态,新增ramdon_tests/async_program_surface_examples/76_async_main_guarded_static_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql,锁定退出码65;本轮再继续把同一路径推进到 double-root alias + alias-sourced composed dynamic 形态,新增ramdon_tests/async_program_surface_examples/77_async_main_guarded_static_alias_backed_double_root_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql,锁定退出码69;并继续推进到 double-root double-source alias + alias-sourced composed dynamic 形态,新增ramdon_tests/async_program_surface_examples/78_async_main_guarded_static_alias_backed_double_root_double_source_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql,锁定退出码71;随后再推进到 row alias 形态,新增ramdon_tests/async_program_surface_examples/79_async_main_guarded_static_alias_backed_double_root_double_source_row_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql,锁定退出码73;继续推进到 row/slot alias 形态,新增ramdon_tests/async_program_surface_examples/80_async_main_guarded_static_alias_backed_double_root_double_source_row_slot_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql,锁定退出码77;最后继续推进到 triple-root 与 triple-source 形态,新增ramdon_tests/async_program_surface_examples/81_async_main_guarded_static_alias_backed_triple_root_double_source_row_slot_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql与82_async_main_guarded_static_alias_backed_triple_root_triple_source_row_slot_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql,锁定退出码79 / 81。 - guard-refined projected-root alias-root canonicalization 的 current program subset 现也已进入同一条 public regression matrix:
async fn main下的let alias = pending.tasks; if slot.value == 0 { let first = await alias[slot.value]; pending.tasks[0] = worker(...) } let second = await alias[0]现也已覆盖BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable,说明 equality-guard refinement 与 alias-root canonicalization 在 aggregate field root 形态下也能稳定复用同一条 literal/projection path - const-backed + guard-refined projected-root alias-root canonicalization 的 current program subset 现也已进入同一条 public regression matrix:
async fn main下的let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { let first = await alias[slot.value]; pending.tasks[0] = worker(...) } let second = await alias[0]现也已覆盖BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable,说明 same-file const item、equality-guard refinement 与 alias-root canonicalization 的三者组合不会在 program mode 下重新分叉 - composed stable-dynamic 与 alias-sourced composed dynamic program path 现也已补齐 emit parity:
await tasks[slots[row]]; tasks[slots[row]] = ...; await tasks[slots[row]]与await tasks[alias[row]]; tasks[slots[row]] = ...; await tasks[alias[row]]已进入BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable的 public regression matrix,说明 stable-dynamic path 的递归组合与一层 immutable alias 不再只在exe/ library build 里被隐式覆盖 - 最近两轮新增的 guard-refined helper path 与 projected-root program path 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/10_async_main_guard_refined_projected_root.ql会把if index == 0 { await tasks[index]; tasks[0] = ... }与await pending.tasks[slot.value]; pending.tasks[slot.value] = ...组合到同一条真实运行样例,ramdon_tests/async_program_surface_examples/11_async_main_const_backed_projected_root.ql则单独锁住await pending.tasks[INDEX]; pending.tasks[0] = ...; await pending.tasks[INDEX]这条 const-backed projected-root 形态;两者都由ql-clismoke harness 锁定退出码,避免这些路径只停留在“可构建”而缺少用户可运行示例 - projected-root alias-root canonicalization 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/12_async_main_aliased_projected_root.ql会单独锁住let alias = pending.tasks; await alias[slot.value]; pending.tasks[slot.value] = ...; await alias[slot.value]这条 source-root reinit 恢复 alias 可用性的 program path,并由ql-clismoke harness 锁定退出码,避免这条路径继续停留在“分析/构建通过”而缺少真实运行 contract - const-backed projected-root alias-root canonicalization 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/13_async_main_aliased_const_backed_projected_root.ql会单独锁住let alias = pending.tasks; await alias[INDEX]; pending.tasks[0] = ...; await alias[INDEX]这条 same-file const item 驱动的 alias-root projected-root 路径,并由ql-clismoke harness 锁定退出码,避免这条相邻变体继续依赖“相邻 contract 已覆盖”的隐式假设 - guard-refined projected-root alias-root canonicalization 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/14_async_main_aliased_guard_refined_projected_root.ql会单独锁住let alias = pending.tasks; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } await alias[0]这条 equality-guard + alias-root 组合路径,并由ql-clismoke harness 锁定退出码,避免这条相邻变体继续停留在“本地已验证但仓内无 contract” - const-backed + guard-refined projected-root alias-root canonicalization 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/15_async_main_aliased_guard_refined_const_backed_projected_root.ql会单独锁住let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } await alias[0]这条三者组合路径,并由ql-clismoke harness 锁定退出码,避免它继续依赖前两轮相邻 contract 的隐式覆盖 - alias-fed tuple repackage after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/16_async_main_aliased_projected_root_tuple_repackage_reinit.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let pair = (alias[slot.value], worker(...)); await pair[0]这条“alias-root projected task handle 经 tuple 重新包装后继续可用”的 program path,并由ql-clismoke harness 锁定退出码,避免这条更贴近真实用户写法的 aggregate repackage 路径继续只停留在 library-mode contract - alias-fed struct repackage after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/17_async_main_aliased_projected_root_struct_repackage_reinit.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let bundle = Bundle { left: alias[slot.value], right: worker(...) }; await bundle.left这条“alias-root projected task handle 经 struct 重新包装后继续可用”的 program path,并由ql-clismoke harness 锁定退出码,把 aggregate repackage 从 tuple 再推进到用户更常写的 named aggregate 形态 - alias-fed nested aggregate repackage after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/18_async_main_aliased_projected_root_nested_repackage_reinit.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let env = Envelope { bundle: Bundle { left: alias[slot.value], right: worker(...) }, tail: pending.tasks[1] }; await env.bundle.left这条“alias-root projected task handle 经多层 aggregate 封装后继续可用”的 program path,并由ql-clismoke harness 锁定退出码,把 aggregate repackage 再推进到 nested object 形态 - const-backed + guard-refined nested aggregate repackage after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/19_async_main_aliased_guard_refined_const_backed_nested_repackage_reinit.ql会单独锁住let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } let env = Envelope { bundle: Bundle { left: alias[slot.value], right: worker(...) }, tail: pending.tasks[1] }; await env.bundle.left这条“const/guard/alias/nested aggregate 四者组合”路径,并由ql-clismoke harness 锁定退出码,把 nested aggregate repackage 进一步推进到组合 contract - alias-fed nested aggregate repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/20_async_main_aliased_projected_root_nested_repackage_spawn.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let env = Envelope { bundle: Bundle { left: alias[slot.value], right: worker(...) }, tail: pending.tasks[1] }; let running = spawn env.bundle.left这条“重包装后再提交任务句柄”的 program path,并由ql-clismoke harness 锁定退出码,把 nested aggregate repackage 从await进一步推进到spawn -> await running组合 - const-backed + guard-refined nested aggregate repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/21_async_main_aliased_guard_refined_const_backed_nested_repackage_spawn.ql会单独锁住let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } let env = Envelope { bundle: Bundle { left: alias[slot.value], right: worker(...) }, tail: pending.tasks[1] }; let running = spawn env.bundle.left这条“const/guard/alias/nested aggregate/spawn 五者组合”路径,并由ql-clismoke harness 锁定退出码,把 nested aggregate submit surface 再推进到组合 contract - alias-fed fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/22_async_main_aliased_projected_root_array_repackage_spawn.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let tasks = [alias[slot.value], worker(...)] ; let running = spawn tasks[0]这条“重包装进 fixed array 后再提交任务句柄”的 program path,并由ql-clismoke harness 锁定退出码,把 alias-root aggregate repackage 补齐到 array 形态 - const-backed + guard-refined fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/23_async_main_aliased_guard_refined_const_backed_array_repackage_spawn.ql会单独锁住let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } let tasks = [alias[slot.value], worker(...)] ; let running = spawn tasks[0]这条“const/guard/alias/fixed-array repackage/spawn 五者组合”路径,并由ql-clismoke harness 锁定退出码,把 array submit surface 继续推进到更完整的组合 contract - alias-fed nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/24_async_main_aliased_projected_root_nested_array_repackage_spawn.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let env = Envelope { bundle: Bundle { tasks: [alias[slot.value], worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“先嵌入对象、再经 fixed-array 子字段提交任务句柄”的 program path,并由ql-clismoke harness 锁定退出码,把 array submit surface 再推进到 nested aggregate 形态 - const-backed + guard-refined nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/25_async_main_aliased_guard_refined_const_backed_nested_array_repackage_spawn.ql会单独锁住let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } let env = Envelope { bundle: Bundle { tasks: [alias[slot.value], worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“const/guard/alias/nested fixed-array repackage/spawn 六者组合”路径,并由ql-clismoke harness 锁定退出码,把 nested array submit surface 继续推进到更完整的组合 contract - composed-dynamic nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/26_async_main_composed_dynamic_nested_array_repackage_spawn.ql会单独锁住let row = choose(); let slots = [row, row]; let alias = pending.tasks; let first = await alias[slots[row]]; pending.tasks[slots[row]] = ...; let env = Envelope { bundle: Bundle { tasks: [alias[slots[row]], worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“stable-dynamic path 先重包装进 nested fixed-array aggregate 再提交”的 program path,并由ql-clismoke harness 锁定退出码,把 nested array submit surface 再推进到 composed-dynamic 形态 - alias-sourced composed-dynamic nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/27_async_main_alias_sourced_composed_dynamic_nested_array_repackage_spawn.ql会单独锁住let row = choose(); let slots = [row, row]; let alias_slots = slots; let alias = pending.tasks; let first = await alias[alias_slots[row]]; pending.tasks[slots[row]] = ...; let env = Envelope { bundle: Bundle { tasks: [alias[alias_slots[row]], worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“stable-dynamic source path 再经 immutable alias 后重包装进 nested fixed-array aggregate 并提交”的 program path,并由ql-clismoke harness 锁定退出码,把 nested array submit surface 再推进到 alias-sourced composed-dynamic 形态 - const-backed + guard-refined alias-sourced composed-dynamic nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/28_async_main_guarded_alias_sourced_composed_dynamic_nested_array_repackage_spawn.ql会单独锁住let row = choose(); let slots = [row, row]; let alias_slots = slots; let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [alias[alias_slots[row]], worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“const/guard + alias-sourced stable-dynamic path 再流经 nested fixed-array aggregate 并提交”的 program path,并由ql-clismoke harness 锁定退出码,把 nested array submit surface 再推进到更完整的 stable-dynamic 组合 contract - helper-forwarded nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/29_async_main_aliased_projected_root_forwarded_nested_array_repackage_spawn.ql会单独锁住let alias = pending.tasks; let first = await alias[slot.value]; pending.tasks[slot.value] = ...; let env = Envelope { bundle: Bundle { tasks: [forward(alias[slot.value]), worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“helper 形参流动的 task handle 再重包装进 nested fixed-array aggregate 并提交”的 program path,并由ql-clismoke harness 锁定退出码,把 helper task-handle 与 nested array submit 两条 surface 正式接通 - const-backed + guard-refined helper-forwarded nested fixed-array repackage spawn after source-root reinit 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/30_async_main_aliased_guard_refined_const_backed_forwarded_nested_array_repackage_spawn.ql会单独锁住let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[slot.value]; pending.tasks[0] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[slot.value]), worker(...)] }, tail: pending.tasks[1] }; let running = spawn env.bundle.tasks[0]这条“const/guard + helper-forwarded task handle 再流经 nested fixed-array aggregate 并提交”的 program path,并由ql-clismoke harness 锁定退出码,把 helper task-handle 与 nested array submit 的组合 contract 继续补齐 - alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling task field 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/31_async_main_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn_with_tail_field.ql会单独锁住let row = choose(); let slots = [row, row]; let alias_slots = slots; let alias = pending.tasks; let first = await alias[alias_slots[row]]; pending.tasks[slots[row]] = ...; let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tail }这条“alias-sourced composed-dynamic task handle 先经 helper 转发、再嵌入 nested fixed-array aggregate,同时保留 sibling task field 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 helper-forwarded surface 正式推进到 alias-sourced composed-dynamic 组合形态 - const-backed + guard-refined alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling task field 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/32_async_main_guarded_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn_with_tail_field.ql会单独锁住let row = choose(); let slots = [row, row]; let alias_slots = slots; let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tail }这条“const/guard + alias-sourced composed-dynamic task handle 再经 helper 转发,并与 sibling task field 并存”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 alias-sourced composed-dynamic 组合形态 - const-backed alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/33_async_main_const_backed_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row = INDEX; let slots = [row, row]; let alias_slots = slots; let alias = pending.tasks; let first = await alias[alias_slots[row]]; pending.tasks[slots[row]] = ...; let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“same-file const-backed + alias-sourced composed-dynamic task handle 再经 helper 转发,并恢复到 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 helper-forwarded surface 正式推进回同数组兄弟元素形态 - guarded const-backed alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/34_async_main_guarded_const_backed_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row = INDEX; let slots = [row, row]; let alias_slots = slots; let alias = pending.tasks; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed alias-sourced composed-dynamic task handle 再经 helper 转发,并恢复到 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进回同数组兄弟元素形态 - guarded const-backed double-root-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/35_async_main_guarded_const_backed_double_root_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row = INDEX; let slots = [row, row]; let alias_slots = slots; let root = pending.tasks; let alias = root; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed + double-root alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到双根别名组合形态 - guarded const-backed double-root-aliased double-source-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/36_async_main_guarded_const_backed_double_root_double_source_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row = INDEX; let slots = [row, row]; let slot_root = slots; let alias_slots = slot_root; let root = pending.tasks; let alias = root; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed + double-root alias + double-source alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到双根双源别名组合形态 - guarded const-backed double-root-aliased double-source-aliased row-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/37_async_main_guarded_const_backed_double_root_double_source_row_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let alias_slots = slot_root; let root = pending.tasks; let alias = root; let slot = Slot { value: INDEX }; if slot.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed + row alias + double-root alias + double-source alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到双根双源加 row alias 的组合形态 - guarded const-backed double-root-aliased double-source-aliased row-aliased slot-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/38_async_main_guarded_const_backed_double_root_double_source_row_slot_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let alias_slots = slot_root; let root = pending.tasks; let alias = root; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed + slot alias + row alias + double-root alias + double-source alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到双根双源加 row/slot alias 的组合形态 - guarded const-backed triple-root-aliased double-source-aliased row-aliased slot-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/39_async_main_guarded_const_backed_triple_root_double_source_row_slot_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let alias_slots = slot_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed + triple-root alias + slot alias + row alias + double-source alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 triple-root + row/slot alias 的组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/40_async_main_guarded_const_backed_triple_root_triple_source_row_slot_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: pending.tasks[1] }这条“const/guard + same-file const-backed + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 triple-root + triple-source + row/slot alias 的组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/41_async_main_guarded_const_backed_triple_root_triple_source_row_slot_tail_alias_sourced_composed_dynamic_forwarded_nested_array_repackage_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let env = Envelope { bundle: Bundle { tasks: [forward(alias[alias_slots[row]]), worker(...)] }, tail: tail_tasks[1] }这条“const/guard + same-file const-backed + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 triple-root + triple-source + row/slot/tail alias 的组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/42_async_main_guarded_const_backed_triple_root_triple_source_row_slot_tail_alias_sourced_composed_dynamic_forwarded_alias_nested_array_repackage_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let forwarded = forward(alias[alias_slots[row]]); let running_task = forwarded; let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }这条“const/guard + same-file const-backed + forwarded alias + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 forwarded-alias 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased queued-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/43_async_main_guarded_const_backed_triple_root_triple_source_tail_queued_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let forwarded = forward(alias[alias_slots[row]]); let running_task = forwarded; let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }; let queued = env.bundle.tasks[0]; let running = spawn queued这条“const/guard + same-file const-backed + queued alias before spawn + forwarded alias + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 queued-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased queued-root-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/44_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let forwarded = forward(alias[alias_slots[row]]); let running_task = forwarded; let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }; let queued_tasks = env.bundle.tasks; let queued = queued_tasks[0]; let running = spawn queued这条“const/guard + same-file const-backed + queued root alias before spawn + forwarded alias + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 queued-root-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased queued-root-aliased-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/45_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_alias_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let forwarded = forward(alias[alias_slots[row]]); let running_task = forwarded; let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }; let queue_root = env.bundle.tasks; let queued_tasks = queue_root; let queued = queued_tasks[0]; let running = spawn queued这条“const/guard + same-file const-backed + queued root alias before spawn 再多一层 immutable alias + forwarded alias + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 queued-root-aliased-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased queued-root-chain-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/46_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_chain_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let forwarded = forward(alias[alias_slots[row]]); let running_task = forwarded; let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }; let queue_root = env.bundle.tasks; let queue_alias_root = queue_root; let queued_tasks = queue_alias_root; let queued = queued_tasks[0]; let running = spawn queued这条“const/guard + same-file const-backed + queued root alias before spawn 再多一层 immutable alias chain + forwarded alias + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 queued-root-chain-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased queued-local-aliased-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/47_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_local_alias_spawn.ql会单独锁住let row_root = INDEX; let row = row_root; let slots = [row, row]; let slot_root = slots; let slot_alias_root = slot_root; let alias_slots = slot_alias_root; let root = pending.tasks; let root_alias = root; let alias = root_alias; let slot = Slot { value: INDEX }; let slot_alias = slot; if slot_alias.value == 0 { await alias[alias_slots[row]]; pending.tasks[slots[row]] = ... } let tail_tasks = pending.tasks; let forwarded = forward(alias[alias_slots[row]]); let running_task = forwarded; let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }; let queue_root = env.bundle.tasks; let queue_alias_root = queue_root; let queued_tasks = queue_alias_root; let queued = queued_tasks[0]; let queued_alias = queued; let running = spawn queued_alias这条“const/guard + same-file const-backed + queued local alias before spawn 叠加在 queued-root alias chain 之上 + forwarded alias + tail alias + triple-source alias + triple-root alias + row/slot alias + alias-sourced composed-dynamic task handle 再经 helper 转发,并继续保留 sibling array element 可用”的 program path,并由ql-clismoke harness 锁定退出码,把 guarded helper-forwarded surface 继续推进到 queued-local-aliased-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased forwarded-aliased queued-local-chain-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/48_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_local_chain_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root、let queued = queued_tasks[0]、let queued_alias = queued、let queued_final = queued_alias与spawn queued_final,把 guarded helper-forwarded surface 继续推进到 queued-local-chain-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased double-forwarded queued-local-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/49_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_local_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root、let queued = queued_tasks[0]、let queued_alias = queued、let queued_final = queued_alias、let queued_ready = forward(queued_final)与spawn queued_ready,把 guarded helper-forwarded surface 继续推进到 queued-local-forwarded-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased inline-double-forwarded queued-local-before-spawn alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/50_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_local_inline_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root、let queued = queued_tasks[0]、let queued_alias = queued、let queued_final = queued_alias与spawn forward(queued_final),把 guarded helper-forwarded surface 继续推进到 queued-local-inline-forward-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/51_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_inline_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }与spawn forward(env.bundle.tasks[0]),把 guarded helper-forwarded surface 继续推进到 bundle-inline-forward-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-slot-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/52_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_slot_inline_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_slot = Slot { value: INDEX }、let bundle_slot_alias = bundle_slot与spawn forward(env.bundle.tasks[bundle_slot_alias.value]),把 guarded helper-forwarded surface 继续推进到 bundle-slot-inline-forward-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased tail-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/53_async_main_guarded_const_backed_triple_root_triple_source_tail_direct_inline_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }与spawn forward(env.tail),把 guarded helper-forwarded surface 继续推进到 tail-inline-forward-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased tail-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/54_async_main_guarded_const_backed_triple_root_triple_source_tail_direct_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }与await forward(env.tail),把 guarded helper-forwarded surface 继续推进到 tail-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-slot-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/55_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_slot_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_slot = Slot { value: INDEX }、let bundle_slot_alias = bundle_slot与await forward(env.bundle.tasks[bundle_slot_alias.value]),把 guarded helper-forwarded surface 继续推进到 bundle-slot-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/56_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }与await forward(env.bundle.tasks[0]),把 guarded helper-forwarded surface 继续推进到 bundle-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-local-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/57_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_local_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root、let queued = queued_tasks[0]、let queued_alias = queued、let queued_final = queued_alias与await forward(queued_final),把 guarded helper-forwarded surface 继续推进到 queued-local-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased double-forwarded queued-local-before-await alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/58_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_local_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root、let queued = queued_tasks[0]、let queued_alias = queued、let queued_final = queued_alias、let queued_ready = forward(queued_final)与await queued_ready,把 guarded helper-forwarded surface 继续推进到 queued-local-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-root-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/59_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queued_tasks = env.bundle.tasks与await forward(queued_tasks[0]),把 guarded helper-forwarded surface 继续推进到 queued-root-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-root-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/60_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queued_tasks = env.bundle.tasks、let queued = queued_tasks[0]、let queued_ready = forward(queued)与await queued_ready,把 guarded helper-forwarded surface 继续推进到 queued-root-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-root-aliased-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/61_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_alias_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queued_tasks = queue_root、let queued = queued_tasks[0]、let queued_ready = forward(queued)与await queued_ready,把 guarded helper-forwarded surface 继续推进到 queued-root-aliased-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-root-chain-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/62_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_chain_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root、let queued = queued_tasks[0]、let queued_ready = forward(queued)与await queued_ready,把 guarded helper-forwarded surface 继续推进到 queued-root-chain-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-root-aliased-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/63_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_alias_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queued_tasks = queue_root与await forward(queued_tasks[0]),把 guarded helper-forwarded surface 继续推进到 queued-root-aliased-inline-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased queued-root-chain-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/64_async_main_guarded_const_backed_triple_root_triple_source_tail_queue_root_chain_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let queue_root = env.bundle.tasks、let queue_alias_root = queue_root、let queued_tasks = queue_alias_root与await forward(queued_tasks[0]),把 guarded helper-forwarded surface 继续推进到 queued-root-chain-inline-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/65_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_tasks = env.bundle.tasks、let bundled = bundle_tasks[0]、let bundle_ready = forward(bundled)与await bundle_ready,把 guarded helper-forwarded surface 继续推进到 bundle-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-aliased-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/66_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_alias_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_root = env.bundle.tasks、let bundle_tasks = bundle_root、let bundled = bundle_tasks[0]、let bundle_ready = forward(bundled)与await bundle_ready,把 guarded helper-forwarded surface 继续推进到 bundle-aliased-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-chain-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/67_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_chain_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_root = env.bundle.tasks、let bundle_alias_root = bundle_root、let bundle_tasks = bundle_alias_root、let bundled = bundle_tasks[0]、let bundle_ready = forward(bundled)与await bundle_ready,把 guarded helper-forwarded surface 继续推进到 bundle-chain-forwarded-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-aliased-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/68_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_alias_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_root = env.bundle.tasks、let bundle_tasks = bundle_root与await forward(bundle_tasks[0]),把 guarded helper-forwarded surface 继续推进到 bundle-aliased-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-chain-inline-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage await with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/69_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_chain_inline_forward_await.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_root = env.bundle.tasks、let bundle_alias_root = bundle_root、let bundle_tasks = bundle_alias_root与await forward(bundle_tasks[0]),把 guarded helper-forwarded surface 继续推进到 bundle-chain-inline-forward-before-await 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/70_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_tasks = env.bundle.tasks、let bundled = bundle_tasks[0]、let bundle_ready = forward(bundled)与spawn bundle_ready,把 guarded helper-forwarded surface 继续推进到 bundle-forwarded-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-aliased-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/71_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_alias_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_root = env.bundle.tasks、let bundle_tasks = bundle_root、let bundled = bundle_tasks[0]、let bundle_ready = forward(bundled)与spawn bundle_ready,把 guarded helper-forwarded surface 继续推进到 bundle-aliased-forwarded-before-spawn 组合形态 - guarded const-backed triple-root-aliased triple-source-aliased row-aliased slot-aliased tail-aliased bundle-chain-forwarded alias-sourced composed-dynamic helper-forwarded nested fixed-array repackage spawn with sibling array element 现也已进入 committed executable examples:
ramdon_tests/async_program_surface_examples/72_async_main_guarded_const_backed_triple_root_triple_source_tail_bundle_chain_forward_spawn.ql会单独锁住let tail_tasks = pending.tasks、let forwarded = forward(alias[alias_slots[row]])、let running_task = forwarded、let env = Envelope { bundle: Bundle { tasks: [running_task, worker(...)] }, tail: tail_tasks[1] }、let bundle_root = env.bundle.tasks、let bundle_alias_root = bundle_root、let bundle_tasks = bundle_alias_root、let bundled = bundle_tasks[0]、let bundle_ready = forward(bundled)与spawn bundle_ready,把 guarded helper-forwarded surface 继续推进到 bundle-chain-forwarded-before-spawn 组合形态 staticlib已开放第一条受控 async library build 子集dylib已开放最小受控 async library build 子集:当前允许带内部 async helper 的 library body 通过,真实 shared-library 产物也会内联最小 runtime hook 定义以保证可链接,但公开导出面仍收敛在同步extern "c"C ABI surfacellvm-ir/object已开放当前 async program build 子集:async fn main及其当前已支持的await/spawn/ fixed-arrayfor await路径现在可以直接产出 LLVM IR 或对象文件for await已开放首个受控 lowering 竖切片:当前支持 library-mode async body,以及BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executableasync fn main子集内对 fixed-shape iterable 的 lowering;当前 fixed-shape 覆盖 fixed array 与 homogeneous tuple- committed
examples/ffi-c/examples/ffi-c-dylib/examples/ffi-rust宿主示例与对应回归测试已经建立
当前仍刻意未开放
这些边界仍然应该明确写成“未完成”,而不是模糊描述成“后面再看”:
- 更广义的 projection-sensitive ownership / partial-place move tracking(当前已开放 tuple/struct-field task-handle path 的只读 consume 与同路径 write/reinit、fixed-array literal index task-handle path 的只读 consume/write-reinit,以及 dynamic fixed-array index task-handle 的 sibling-safe consume + same immutable stable index path precise consume/reinit 子集,其中 stable source path 现也可递归组合到
tasks[slots[row]]这类 composed dynamic index,并继续穿过let alias = slots这类 immutable alias;同一条稳定 source path 现也可在if index == 0/if slot.value == 0这类 equality guard 的 dominated branch 内保守回收到 literal/projection path;非Task[...]元素 dynamic array assignment 已开放,而 generic dynamicTask[...]overlap / reinit reasoning 仍未开放) - 更广义的 projection assignment lowering(当前已开放 tuple index / struct-field / fixed-array literal index projection write/reinit、非
Task[...]元素的 dynamic array assignment,以及Task[...]dynamic array 的 generic maybe-overlap write/reinit + same immutable stable index path precise consume/reinit 子集) - 更广义的
for awaitlowering(当前已开放 library-mode 与BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executableasync fn main子集下的 fixed-shape iterable;当前 fixed-shape 覆盖 fixed-array 与 homogeneous tuple) - cancellation / polling / drop 语义
- generic async ABI 与 layout substitution
- 更广义的 async
dylib构建承诺(当前仅开放带同步extern "c"导出面的最小 library-style async body 子集) - 更广义的 async executable surface(当前仅开放
BuildEmit::LlvmIr/BuildEmit::Object/BuildEmit::Executable下的async fn main最小 program surface;更复杂的 program/runtime bootstrap 仍未开放) - 更广义的 task result transport 协议
- 更广义的 place-sensitive task-handle lifecycle(当前 dynamic array 只开放“sibling-safe consume + same immutable stable index path precise consume/reinit + generic dynamic maybe-overlap”这条保守子集)
推进阶段记录
P7.1 收紧 task-handle 语义与 ownership 边界 ✓ 已完成(2026-03-29)
所有目标均已落地:
- projected task-handle consume/write-reinit(tuple/struct-field/fixed-array literal index)已在 typeck/borrowck/codegen/driver/CLI 各层锁定
- branch-join、cleanup、helper forward/reinit 定向回归均已完成
- 非
Task[...]元素 dynamic array assignment 已在ql-driver内部单测与ql-cli黑盒层锁定 Task[...]动态数组索引赋值的 fail contract 已在 driver/CLI 两层补齐
详细执行记录见 2026-03-28 近期优先级计划。
P7.2 runtime hook ABI 合同细化 ✓ 已完成(2026-03-29)
目标:把当前 backend 中隐含的 hook 合同假设补成显式文档和测试。
不扩新 hook,不引入多态变体。只把”opaque ptr 指向可直接 load 的 payload”这类现有假设在 ql-runtime 里写成注释规约,并在单测中体现。
已落地:
ql-runtime/src/lib.rs:每条 hook symbol 补充完整 caller/callee 生命周期约定注释,enum-level overview 展示两组生命周期,TaskAwait明确”backend load assumption”ql-runtime/tests/executor.rs:新增三项生命周期单测,14 项全通过ql-codegen-llvm/src/lib.rs:await lowering load 位置补充 INVARIANT 注释,显式引用RuntimeHook::TaskAwait合同
详细任务分解见 2026-03-29 P7.2 计划。
P7.3 扩 Rust interop 双向工作流矩阵 ✓ 已完成(2026-03-29)
目标:把 examples/ffi-rust 从单向 export 示例扩展到更接近真实双向互操作的场景。
不新增 ABI surface,不引入跨 crate 模块系统。只把”Qlang 导出 + 导入 C/Rust callback”这条双向路径在示例和 CLI 集成测试中锁定。
已落地:
examples/ffi-rust/ql/callback_add.ql:新增q_host_multiplyimport 与q_scaleexport,建立第二条独立双向路径examples/ffi-rust/host/src/main.rs:提供两个 Rust 回调,调用两个 Qlang 导出,两条路径均验证返回 42crates/ql-cli/tests/ffi.rs:ffi_rust_example_cargo_host_runs扩展断言q_scale(6, 7) = 42
详细任务分解见 2026-03-29 P7.2 计划。
P7.4 扩大 async build surface(条件评估)
首个 program-build 切片已落地:BuildEmit::Executable 现已开放 async fn main 的最小程序入口生命周期,并已锁定 async fn main + fixed-shape for await 的 executable 闭环。当前 fixed-shape 覆盖 fixed-array 与 homogeneous tuple。其余方向仍按下述前提继续保守推进,其中 Task 4 已完成 docs-first 评估并继续 deferred。
以下四个方向各有明确的推进前提,满足条件前继续保持保守拒绝:
| 方向 | 推进前提 |
|---|---|
放宽更多 await/spawn payload 路径 | runtime hook 合同(P7.2)已在单测层稳定,且 result layout contract 在注释中显式 |
扩大 for await iterable surface(slice/span 或通用 iterator) | 已完成 docs-first 评估:在 qlrt_async_iter_next 仍是 placeholder 的前提下,继续只开放 fixed-array;只有当 Slice[T] / span-like view 能作为 compiler-driven fixed-shape lowering 落地,且无需冻结新的 item release 协议时,才进入下一刀实现 |
扩大 async dylib 或开放更多 async program build surface | 至少一条 Rust host 双向互操作路径(P7.3)已被 CI 锁定,且 hook ABI 文档已成立;当前已开放 BuildEmit::LlvmIr / BuildEmit::Object / BuildEmit::Executable 下的 async fn main 最小程序入口生命周期 |
| 开放更广义的 async callable / effect surface | Phase 8 或更晚;需要独立 RFC,不在 Phase 7 范围内 |
P7.4 当前执行顺序(2026-04-05 复核)
当前主线不再以 coverage-only matrix 扩写为目标,而是优先消掉已经进入前端/MIR/borrowck 事实面、但 backend 仍明确拦截的用户可见缺口。
Task 3:cleanup lowering / codegen 最小可交付子集
- 状态:当前最高优先级,首个 direct / call-backed
defer+if/match+ 透明?wrapper cleanup 子集已落地,call-backed cleanup 的 callee 与 guard-call 子路径也已接通 callable-value 间接调用的最小切片,并已补上 direct closure-backed callable global、direct local non-capturing closure,以及 direct local capturing closure cleanup callee / cleanup guard-call 的公开回归。 - Why:MIR 已经产生
RegisterCleanup/RunCleanup,borrowck 也已经能分析 guarded dynamic task-handle cleanup;当前这几刀已经把 direct cleanup、guarded call-backed cleanup、callable-value cleanup callee / guard-call、最小 cleanupmatch与 cleanup-internal transparent?接进 build,但更广义的 cleanup control flow 仍是下一段最直接的真实功能缺口。 - 当前范围:
- 继续沿现有 shared lowering 扩 cleanup control-flow,但不引入新 runtime ABI。
- 已开放 direct call / call-backed cleanup expr、callable-value 驱动的 positional indirect cleanup callee / guard-call、带 binding /
_/ tuple destructuring / struct destructuring(叶子仍限 binding /_)最小letstatement 的 statement-sequenced cleanup block、statement-sequenced cleanup guard / scrutinee / call-arg value block、带 body-localbreak/continue的 statement-levelwhile/loopcleanup block、fixed array / homogeneous tuple + binding /_/ tuple destructuring / struct destructuring(叶子仍限 binding /_)pattern 的 statement-levelforcleanup block(当前 iterable 已覆盖 direct root、same-fileconst/staticroot 及其 same-file alias、item-backed read-only projected root、direct call-root、same-file import-alias call-root、nested call-root projected root,以及 transparent?wrapper 下的 projected root),以及 async body 内 fixed-shape iterable 的 statement-level cleanupfor awaitblock(当前根形态已覆盖 direct local root、same-file scalarconst/staticroot、same-file scalar item alias、same-file task-producingconst/staticroot、same-file task item alias root、projected task item root、scalar item-backed read-only projected root、direct block-valued / assignment-valued / runtimeif/match/ awaited direct root、direct question-mark root、read-only projected root、assignment-valued projected root、block-valued projected root、direct call-root、same-file import-alias call-root、nested call-root projected root、awaited projected root、runtimeif/matchaggregate projected root、transparent?wrapper 下的 projected root,以及 inline array/tuple task root)、bool-guardifcleanup branch、支持 single-binding catch-all arm 的 bool/int cleanupmatchbranch,以及这些已开放 cleanup 子路径上的透明?wrapper。 - capturing closure cleanup 现已开放 local alias 未重绑定前提下的 cleanup callee 与 cleanup guard-call 最小子集,并进一步开放 same-target cleanup control-flow 子集、assignment-valued cleanup callee / guard-call root,以及 cleanup
if/match分支里同样收敛到 same-target assignment-valued root 的形态,还有 cleanup block 内局部 alias 的 direct call / guard-call(现含 statement-sequenced local mutable alias same-target reassign、statement-sequenced cleanup block 内局部 mutable alias 的 different-target reassign、assignment-valued same-target binding、control-flow 收敛到 same-target assignment-valued root 的 binding,以及 control-flow 分支内的 block-local alias tail binding;同类 direct cleanup callee / cleanup guard-call root 现在也已接通);同一条 local mutable alias 的 different-target reassign 现在也已扩到 cleanup direct root、cleanup local binding root,以及 runtimeif/matchbranch-join 子集;其中 cleanupifshared-local control-flow assignment-valued binding alias-chain、cleanup boolmatch的等价 alias-chain,以及 cleanup guardedmatch的首个等价 alias-chain 子集现都已接通;different-closure cleanup control-flow 现在也已开放首个 direct-root / block-local-alias-tail-root / block-binding / local-alias-chain-root 子集;cleanupfor await现只开放 fixed-shape iterable 与上述已锁定根形态,更广义的 item-backed projected task root / broader iterable runtime protocol 也继续保守拒绝。
- Deliverables:
ql-codegen-llvm对当前 shipped cleanup 子集不再统一拒绝。ql-driver/ql-cli至少有一条 cleanup build case 从 fail 变 pass,并保留更宽 cleanup surface 的稳定失败合同。- 文档同步更新“已开放 cleanup 子集”和“仍未开放的 broader cleanup surface”。
- 状态:当前最高优先级,首个 direct / call-backed
Task 4:继续扩 callable / cleanup 的最小真实 blocker
- 状态:次优先级,但优先于 coverage-only matrix。
- Why:最小 sync function value 已继续扩到 function-item-backed callable const/static 与 non-capturing sync closure-backed callable const/static 子集,non-capturing sync closure value 也已接入 ordinary positional indirect-call,并继续补上 explicit typed-parameter、statement-level local callable annotation,以及 call-site positional argument 驱动的 parameterized local / immutable-alias 子集;当前又把 capturing sync closure 的 ordinary/call-backed 子集继续推进到 local alias(现含 same-target mutable reassign、different-target reassign、ordinary control-flow assignment-valued direct/binding/alias-chain root,以及 runtime
if/matchbranch-join 子集)、same-target control-flow callable root、ordinary different-closure direct/local-binding-alias-chain/后续未重写块调用 root,以及 cleanup block 内局部 alias(现含 statement-sequenced local mutable alias same-target reassign、statement-sequenced cleanup block 内局部 mutable alias 的 different-target reassign)和 cleanup different-closure control-flow 的首个 direct-root / block-local-alias-tail-root / block-binding / local-alias-chain-root 子集;same-file async function item / alias / callableconst/static也已接入async fn内 ordinary local indirect-call +await;cleanup / guard-call 的 direct closure-backed callable global 与 direct local non-capturing closure 公开回归也已补齐;question-mark blocker 也已消掉;当前最直接的用户可见缺口重新收敛到 other cleanup escape flow,以及 cleanup 内更广 async control-flow。 - Deliverables:
- 优先继续选择“不引入新 runtime ABI”的窄切片。
- 只补与新 lowering 直接对应的最小回归。
Task 5:继续扩 async payload / projection surface
- 状态:降为次优先级。
- Why:当前
await/spawnpayload family、stable-dynamic path、guard-refined path、fixed-shapefor await与 awaitedmatchguard 已形成较大的可用子集;继续堆相邻 matrix 的边际收益,低于 cleanup lowering 这类明确 blocker。 - Deliverables:
- 只在新 lowering 需要时补最小必要回归。
- 不再把“同一路径的相邻变体补齐”作为独立里程碑。
Task 6:保持 deferred 的方向
for await泛化继续按既有 docs-first 结论 deferred:当前仍只开放 fixed-array / homogeneous tuple。- 更广义的 async
dylib、program bootstrap、generic async ABI / layout substitution 继续 deferred。 - Windows toolchain discover 已完成,不再占用当前主线。
Phase 7 出口标准
async fn/await/spawn在当前受控子集上有稳定语义、诊断和回归 ✓(P7.1 已完成)- 至少一条 Rust 混编路径可在 CI 中复现 ✓(
examples/ffi-rust+ CLI 集成测试已建立,P7.3 已扩展为双向双函数) - runtime hook ABI、driver build rejection 与 backend lowering 三者不再互相漂移 ✓(P7.2 已完成:hook 合同注释 + 单测 + INVARIANT 注释对齐)
- 文档、测试、实现三者对当前 async 边界给出同一描述(持续维护中;当前已包含
async fn main的 llvm-ir / object / executable 程序入口子集)
后续阶段
Phase 8:项目级工具链、文档与工作区能力
目标
- 建立 project/workspace 级开发体验,而不仅是单文件或 same-file 语义
- 建立文档产物、包管理与模板初始化能力
- 让新用户从模板、文档、构建、编辑器到混编形成更顺畅路径
重点工作
ql doc- lockfile / package / workspace 元数据
- 项目模板与初始化能力
- 跨文件 / 项目级 semantic index
- 在 P6 same-file 基础上扩展 cross-file query / references / rename / completion
当前执行顺序(2026-04-05)
- 当前不建议直接从 Phase 6 的 same-file LSP 跳到 cross-file rename / 全量 workspace IDE。
- 推荐顺序已经固定为:
package/workspace graph -> .qi 接口产物 -> ql-analysis 消费依赖 .qi -> ql-lsp cross-file hover/definition/completion/references -> cross-file rename。 .qi应优先被设计成 compiler-facing 的文本接口产物,而不是 LSP 私有缓存;语法风格应保持 Qlang 自身表面,不应漂向 Rust/JSON 专用内部格式。- 这条顺序的前三个最小实现切片已开始落地:仓库现已开放
ql project graph [file-or-dir]、ql project emit-interface [file-or-dir] [-o <output>] [--changed-only] [--check]、ql build <file> --emit-interface、ql check <package-dir> --sync-interfaces、workspace-rootql check [--sync-interfaces]对成员包的批量执行、ql project graph对 package/member 默认.qi路径/状态与引用 interface 状态的展开(现含stale过期标记)、package-awareql check <package-dir>对[references].packages的最小.qiartifact load 与 stale-interface 显式失败合同、ql-analysis::analyze_package的 dependency public symbol index,以及 imported dependency symbol 的最小 cross-file hover / definition / declaration / references、use ...导入路径和平铺 / grouped import 位置里的 package path segment / public symbol completion、dependency enum variant completion、dependency struct explicit field-label completion。 - 当前真实已支持的工程 contract 仍刻意收窄在
[package].name、[workspace].members、[references].packages、.qiV1 emit、ql build <file> --emit-interface的默认 package-level declaration 写出、ql project emit-interface --changed-only对validinterface 的跳过与非validinterface 的定向重发、ql project emit-interface --check对默认 package/member interface 状态的只读校验(workspace--check现会汇总同轮内全部无效 member interface 并输出摘要)、package-awareql check对 dependency.qi的 syntax-aware load(当前入口已覆盖 package dir / manifest / package source file / workspace-only root manifest,并会把 stale dependency interface 视为显式失败)、ql check --sync-interfaces对本地引用包默认.qi的递归同步写出(当前入口也已覆盖 package dir / manifest / package source file / workspace-only root manifest,并会对重复 dependency 写出做去重;当前只对非validinterface 重发)、ql project graph对 package/member 默认.qi路径/状态与引用 interface 状态的展开、package 级 dependency public symbol index,以及 imported dependency symbol 到.qideclaration 的最小 hover / definition / declaration / references、use ...导入路径和平铺 / grouped import 位置里的 dependency package path segment / public symbol completion、dependency enum variant completion,与 dependency struct explicit field-label completion;grouped import alias 当前也已明确落在这条 cross-file query 合同里,而 grouped import 空补全位会跳过已写过的 dependency item;explicit struct field-label completion 当前也会跳过同一字面量/模式里已经写过的 sibling 字段;cross-file rename、更广义 completion、真实 build graph 还没有开。 - cross-file rename、code actions、call hierarchy 继续后置,等 dependency symbol identity 与 workspace edit graph 稳定后再开。
- 这条顺序的入口设计稿见:2026-04-05 Phase 8:
.qi接口产物与 Cross-File LSP 设计入口。
出口标准
- 新项目可以从模板初始化到构建运行形成稳定闭环
- 文档产物、workspace 元数据与编辑器语义形成统一工程面
Phase 9:深水区语义、运行时与性能
目标
- 在已有地基上推进更广义的语言与运行时能力
- 建立更成熟的编译性能、增量分析和生态支撑
重点工作
- 更广义的 ownership / borrow / drop 规则
- 更完整的 async/runtime/effect 设计
- 更成熟的增量编译与性能回归体系
- 更深的 C++ 互操作
- 更成熟的标准库、生态与工程工具
出口标准
- 项目进入“可持续扩展”的生态阶段,而不是继续靠单点人工推进
每个阶段都必须交付的横向事项
无论推进到哪个阶段,以下事项都不是可选项:
- 文档更新
- 示例代码更新
- 回归测试补全
- CI 或验证命令更新
- 重要设计变更的 RFC / ADR 沉淀
对这个项目来说,真正的“完成”不是代码合入,而是下面几件事同时成立:
- 实现已经存在
- 测试能锁住行为
- 文档准确描述当前边界
- 用户能通过 CLI / 示例 / docs 复现正确路径
当前最推荐的阅读顺序
如果你要继续接手这个项目,建议按这个顺序恢复上下文:
这份开发计划的核心结论只有一条:Qlang 当前最重要的工作不是重写基础设施,而是沿着已经成立的前端、语义、中端、后端、FFI、LSP 与 runtime 边界,继续做保守、可验证、可回归的扩展。