feat: update LK VM, syntax, stdlib, and website - #3
Conversation
- Make RuntimeVal derive Copy: all variants are Copy-safe (Nil, Bool, Int, Float, ShortStr, Obj(HeapRef=u32)). No Arc ref-count — GC tracks roots via stack scan. - Simplify Move opcode: eliminate take/clone branch and move_fact query. Now just copies the 16-byte value directly, with batch loop for consecutive Moves. - Inline BrNil/BrNotNil into dispatch loop body with unchecked relative_pc. - Inline ForLoopI jump with unchecked relative_pc. - Inline compare-test branch with unchecked relative_pc for the fallthrough path. - Add relative_pc_unchecked/relative_pc_from_unchecked that elide bounds checks for compiler-generated jump targets. - Make compare_test_value_slow pub(super) for inline access from dispatch loop. - Update two move-heap-clone metric tests: Move no longer tracks copy policy since RuntimeVal is Copy. Geomean: 1.247x (6-sample RUNS=6), down from ~1.27x baseline. binary_search improved to ~1.07x (was ~1.15x).
…ked in ForLoopI - Move rarely-executed opcode handlers (LoadCapture, LoadCellVal, StoreCellVal, LoadFunction, MakeClosure, LoadNative, Not, IsNil, IsList, IsMap, ToString, StringStartsWith, StringSplit, ListJoin, Contains, SliceFrom, MapRest, Raise, TryBegin, TryEnd, Test, BrFalse, BrTrue, NewObject, NewRange, CallNamed, SetGlobal) into a separate #[inline(never)] dispatch_cold function to reduce I-cache pressure on the hot dispatch loop. - Replace relative_pc() with relative_pc_unchecked() in ForLoopI hot path, eliminating bounds check overhead for the loop-back jump. - Geomean improvement: 1.274x → 1.256x (VM vs Lua)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (7)
📜 Recent review details⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
📝 WalkthroughWalkthrough将仓库从 LKR 重命名为 LK 并重构:工作区与构建配置更新,文档与基准重写,CLI 扩展(coverage/pkg/paths/diagnostic)、Parser/AST 常量体系迁移为 LiteralVal,LLVM 后端改为模块工件路径,示例与测试同步更新。 ChangesLK 项目重构与基础设施升级
|
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (5)
README.md (1)
45-49: 💤 Low value可选:修复 markdown 格式问题。
静态分析工具建议在标题前后添加空行以符合 markdown 最佳实践。
📝 建议的格式调整
Run any example: `lk examples/syntax/closure.lk` + ### Highlights🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 45 - 49, Summary: The "### Highlights" heading and surrounding list lack blank lines; add a single blank line before the "### Highlights" heading and a blank line after the list block to conform to Markdown best practices. Locate the "### Highlights" section in README.md, insert an empty line immediately before the "### Highlights" line and an empty line after the last list item ("Project website source lives in `website/`...") so the header and list are separated from surrounding content and render correctly in Markdown.Source: Linters/SAST tools
bench/run_workload_bench.sh (1)
390-392: 💤 Low value空重定向应使用显式的 no-op 命令。
根据 shellcheck SC2188 警告,这些重定向操作缺少命令。虽然在实际运行中可能不会出错,但显式使用
:或true命令会更符合 shell 最佳实践。♻️ 可选的改进方案
- > "$TMPDIR/lk_${name}.dat" - > "$TMPDIR/lua_${name}.dat" - > "$TMPDIR/aot_${name}.dat" + : > "$TMPDIR/lk_${name}.dat" + : > "$TMPDIR/lua_${name}.dat" + : > "$TMPDIR/aot_${name}.dat"类似的修改也适用于 472、500-502 行。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@bench/run_workload_bench.sh` around lines 390 - 392, The three bare redirections writing to "$TMPDIR/lk_${name}.dat", "$TMPDIR/lua_${name}.dat", and "$TMPDIR/aot_${name}.dat" should use an explicit no-op command to satisfy shellcheck SC2188; replace each bare redirection with an explicit no-op (e.g., ":" or "true") followed by the same redirection so the file is created intentionally. Also apply the same change to the other similar bare redirections noted around lines 472 and 500-502 to avoid SC2188 warnings.Source: Linters/SAST tools
cli/src/main_test.rs (1)
67-104: ⚡ Quick win测试可能无法检测到 vm_profile_line 中的字段重复问题。
该测试仅检查输出字符串中是否包含特定字段名(如
val_clones=9),但由于 lines 237-262 中的 bug,多个字段实际上都使用了copy_policy_heap_clones的值。建议在修复
vm_profile_line中的字段映射问题后,增强该测试以验证每个字段的实际数值是否符合预期(而不仅仅是检查子串存在)。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cli/src/main_test.rs` around lines 67 - 104, The vm_profile_line output is incorrectly mapping several heap-clone fields to copy_policy_heap_clones, so update the vm_profile_line implementation to use the correct VmRuntimeMetrics fields (use copy_policy_heap_clones only for its own label and map register_copy_heap_clones, local_copy_heap_clones, local_load_heap_clones, local_store_heap_clones, const_load_heap_clones, call_arg_heap_clones, container_copy_heap_clones, val_clones and heap_clones to their respective output labels) and ensure register_write_sources and index_key_metrics are formatted from their actual arrays; after fixing vm_profile_line, extend the test_vm_profile_line_contains_benchmark_fields test to assert exact numeric substrings for each specific label (e.g., "register_copy_heap_clones=10", "local_copy_heap_clones=12", "local_load_heap_clones=13", "local_store_heap_clones=14", "const_load_heap_clones=15", "call_arg_heap_clones=16", "container_copy_heap_clones=17", "val_clones=9", "heap_clones=9") instead of only existence checks.core/src/ast/parser/literals.rs (1)
43-51: ⚡ Quick win重构错误消息构造方式以消除冗余并提升语义清晰度
当前代码在多处手动格式化 token 到错误消息中,并使用
Token::Nil作为 EOF 占位符,然后再调用self.err(&msg)。这导致两个问题:
- 语义混淆:
Token::Nil在语言中代表nil字面量,而非文件结束标记。- 冗余输出:
err()函数(在support.rs:269-276)已经会自动添加"found {token}"或"found end of input"上下文,手动构造的消息会导致重复信息,例如:"Syntax error: Expecting '}', found Token::Nil (found end of input)"建议将错误消息简化为仅描述期望内容,让
err()统一处理当前 token 或 EOF 的上下文。♻️ 建议的重构方式(以 Lines 70-79 为例)
- if self.eof() || self.tokens[self.pos] != Token::RBrace { - let msg = format!( - "Expecting '}}', found {:?}", - if self.eof() { - &Token::Nil - } else { - &self.tokens[self.pos] - } - ); - return Err(anyhow!(self.err(&msg))); + if self.eof() || self.tokens[self.pos] != Token::RBrace { + return Err(anyhow!(self.err("Expecting '}' to close map literal"))); }对 Lines 43-51、100-108、116-123 应用类似模式。
Also applies to: 70-79, 100-108, 116-123
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/src/ast/parser/literals.rs` around lines 43 - 51, Replace the manual format! + Token::Nil sentinel and the constructed msg with a simple expectation string passed to self.err so err() can append the actual "found ..." or "end of input" context; e.g. in literals.rs where code builds msg with Token::Nil and calls self.err(&msg), remove that formatting and instead return Err(anyhow!(self.err("Invalid map key after comma"))). Apply the same pattern to the other occurrences mentioned (the blocks around the original lines and at the other two similar sites) so no code uses Token::Nil as EOF placeholder and all messages rely on self.err() to provide the found-token context.core/src/ast/parser/support.rs (1)
146-169: ⚡ Quick win建议为闭包块解析使用分离的括号深度计数器
当前
parse_closure_block_expr使用单一depth计数器追踪所有括号类型((),[],{})。这种简化方法对格式良好的代码可以正常工作,但无法检测括号类型不匹配,例如{ foo(] }会被错误地接受为合法的 token 范围。对比
recover_expression_errors(Lines 316-355)为每种括号类型维护独立计数器(paren/bracket/brace),能够更准确地识别嵌套结构。虽然当前实现依赖下游StmtParser捕获错误,但使用分离计数器可以:
- 在更早阶段提供更精确的错误定位
- 避免传递包含不匹配括号的 token 范围给语句解析器
- 提升错误消息的可理解性
♻️ 建议的改进方案
fn parse_closure_block_expr(&mut self) -> Result<Expr> { self.pos += 1; let start = self.pos; - let mut depth = 0i32; + let mut paren_depth = 0i32; + let mut bracket_depth = 0i32; + let mut brace_depth = 0i32; while !self.eof() { match self.tokens[self.pos] { - Token::LBrace | Token::LParen | Token::LBracket => { - depth += 1; + Token::LParen => { + paren_depth += 1; self.pos += 1; } - Token::RParen | Token::RBracket => { - if depth > 0 { - depth -= 1; + Token::RParen => { + if paren_depth > 0 { + paren_depth -= 1; } + if paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 { + // Unmatched closing paren outside closure block + break; + } self.pos += 1; } - Token::RBrace if depth == 0 => break, + Token::LBracket => { + bracket_depth += 1; + self.pos += 1; + } + Token::RBracket => { + if bracket_depth > 0 { + bracket_depth -= 1; + } + if paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 { + break; + } + self.pos += 1; + } + Token::LBrace => { + brace_depth += 1; + self.pos += 1; + } + Token::RBrace if brace_depth == 0 => break, Token::RBrace => { - depth -= 1; + brace_depth -= 1; self.pos += 1; } _ => self.pos += 1, } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/src/ast/parser/support.rs` around lines 146 - 169, parse_closure_block_expr currently uses a single depth counter for all bracket types which lets mismatched brackets (e.g. "{ foo(] }") slip through; update parse_closure_block_expr to use three separate counters (paren, bracket, brace) like recover_expression_errors does, increment/decrement the appropriate counter when encountering Token::LParen/Token::RParen, Token::LBracket/Token::RBracket, and Token::LBrace/Token::RBrace, and only treat Token::RBrace as the closure terminator when brace == 0 while ensuring other counters are adjusted and never go negative so mismatched bracket sequences stop the loop and produce a correct token range/error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bench/run_workload_bench.sh`:
- Line 20: The trap command currently uses double quotes which expands $TMPDIR
at parse time; change the trap invocation in run_workload_bench.sh to use single
quotes so $TMPDIR is expanded when the trap runs (e.g., replace trap "rm -rf
$TMPDIR" EXIT with a single-quoted form) and ensure the variable is quoted
inside the command (use "$TMPDIR") to handle paths with spaces.
- Line 10: 当前脚本把 LK_BIN 硬编码为绝对路径,导致不可移植;请修改 run_workload_bench.sh 以优先使用环境变量
LK_BIN(若已设置且可执行则直接使用),否则在脚本内通过解析脚本目录(例如使用脚本所在目录的相对路径)来推导出相对的 target/release/lk
可执行文件路径并验证可执行性,最后可再尝试用系统路径查找(例如 which lk)作为回退;确保对每种情况做可执行性检查并在失败时打印明确错误并退出。
In `@cli/Cargo.toml`:
- Line 32: 升级 rustyline 到 18 可能改变了 DefaultEditor::new 的签名、ReadlineError 枚举项和引入了
Prompt trait;在 cli/src/repl.rs 中检查并更新对 DefaultEditor::new()
的调用(确保错误处理或返回类型匹配新签名),核对并更新对 ReadlineError 的匹配分支(包括 Interrupted/Eof
名称或模块路径是否变动),并如果你实现或自定义提示/渲染逻辑,改用 rustyline 18 的 Prompt trait 实现或其新的提示 API;修复后运行
REPL 并验证中断/EOF 行为与之前一致。
In `@cli/src/main.rs`:
- Around line 237-262: In vm_profile_line the format string's placeholders for
val_clones, heap_clones and copy_policy_heap_clones are all passed
metrics.copy_policy_heap_clones (a copy-paste bug); open the VmRuntimeMetrics
struct, identify the correct fields (e.g. metrics.val_clones and
metrics.heap_clones if present) and replace the duplicate arguments so the nth
argument matches the nth {} in the format string (keep top_opcode_profile,
top_register_write_source_profile, top_index_key_profile and the other metrics
in the same order). If val_clones should be an aggregate, compute it before the
format call and pass that value instead. Ensure the final argument list length
and order exactly match the placeholders in vm_profile_line.
- Around line 694-701: Fnv64::bytes currently applies two extra operations after
the byte loop (self.0 ^= 0xff; self.0 = self.0.wrapping_mul(0x100000001b3);)
which deviates from the standard FNV-1a algorithm; either remove these two lines
to implement standard FNV-1a behavior in the Fnv64::bytes method or, if this is
an intentional custom finalization, replace them with a clear comment above
Fnv64::bytes explaining the rationale and expected effects of this extra
xor/multiply so future readers know it is deliberate.
In `@core/src/expr/expr_impl.rs`:
- Line 795: The constant-fold for modulo currently invokes fold_literal_numeric
with a raw closure (|a, b| a % b) for BinOp::Mod which will panic on rhs == 0
during compilation; update the implementation so fold_literal_numeric (or the
caller for BinOp::Mod) performs an explicit divide-by-zero check before applying
the modulo: detect rhs == 0 and return a safe failure (e.g., None or propagate
an error) rather than calling the % closure, or change fold_literal_numeric to
accept/handle an operation that returns Option and use a wrapper for Mod that
returns None on zero RHS; reference BinOp::Mod and fold_literal_numeric to
locate and implement this guard.
- Around line 862-874: The constant-folding for division in fold_literal_div
currently converts integer-by-zero cases into float inf/nan; change
fold_literal_div to detect division-by-zero and avoid folding when rhs is zero:
explicitly check when rhs is LiteralVal::Int(b) with *b == 0 and when rhs is
LiteralVal::Float(f) with *f == 0.0 (and for mixed cases ensure
fold_literal_numeric is not invoked when the divisor is zero), and return None
in those cases so the original expression is preserved for runtime
division-by-zero handling.
---
Nitpick comments:
In `@bench/run_workload_bench.sh`:
- Around line 390-392: The three bare redirections writing to
"$TMPDIR/lk_${name}.dat", "$TMPDIR/lua_${name}.dat", and
"$TMPDIR/aot_${name}.dat" should use an explicit no-op command to satisfy
shellcheck SC2188; replace each bare redirection with an explicit no-op (e.g.,
":" or "true") followed by the same redirection so the file is created
intentionally. Also apply the same change to the other similar bare redirections
noted around lines 472 and 500-502 to avoid SC2188 warnings.
In `@cli/src/main_test.rs`:
- Around line 67-104: The vm_profile_line output is incorrectly mapping several
heap-clone fields to copy_policy_heap_clones, so update the vm_profile_line
implementation to use the correct VmRuntimeMetrics fields (use
copy_policy_heap_clones only for its own label and map
register_copy_heap_clones, local_copy_heap_clones, local_load_heap_clones,
local_store_heap_clones, const_load_heap_clones, call_arg_heap_clones,
container_copy_heap_clones, val_clones and heap_clones to their respective
output labels) and ensure register_write_sources and index_key_metrics are
formatted from their actual arrays; after fixing vm_profile_line, extend the
test_vm_profile_line_contains_benchmark_fields test to assert exact numeric
substrings for each specific label (e.g., "register_copy_heap_clones=10",
"local_copy_heap_clones=12", "local_load_heap_clones=13",
"local_store_heap_clones=14", "const_load_heap_clones=15",
"call_arg_heap_clones=16", "container_copy_heap_clones=17", "val_clones=9",
"heap_clones=9") instead of only existence checks.
In `@core/src/ast/parser/literals.rs`:
- Around line 43-51: Replace the manual format! + Token::Nil sentinel and the
constructed msg with a simple expectation string passed to self.err so err() can
append the actual "found ..." or "end of input" context; e.g. in literals.rs
where code builds msg with Token::Nil and calls self.err(&msg), remove that
formatting and instead return Err(anyhow!(self.err("Invalid map key after
comma"))). Apply the same pattern to the other occurrences mentioned (the blocks
around the original lines and at the other two similar sites) so no code uses
Token::Nil as EOF placeholder and all messages rely on self.err() to provide the
found-token context.
In `@core/src/ast/parser/support.rs`:
- Around line 146-169: parse_closure_block_expr currently uses a single depth
counter for all bracket types which lets mismatched brackets (e.g. "{ foo(] }")
slip through; update parse_closure_block_expr to use three separate counters
(paren, bracket, brace) like recover_expression_errors does, increment/decrement
the appropriate counter when encountering Token::LParen/Token::RParen,
Token::LBracket/Token::RBracket, and Token::LBrace/Token::RBrace, and only treat
Token::RBrace as the closure terminator when brace == 0 while ensuring other
counters are adjusted and never go negative so mismatched bracket sequences stop
the loop and produce a correct token range/error.
In `@README.md`:
- Around line 45-49: Summary: The "### Highlights" heading and surrounding list
lack blank lines; add a single blank line before the "### Highlights" heading
and a blank line after the list block to conform to Markdown best practices.
Locate the "### Highlights" section in README.md, insert an empty line
immediately before the "### Highlights" line and an empty line after the last
list item ("Project website source lives in `website/`...") so the header and
list are separated from surrounding content and render correctly in Markdown.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e0720731-23a7-4d0c-9bb7-ccfb7183186a
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (299)
.github/workflows/perf-dashboard.yml.gitignoreCargo.tomlLANG.mdLANG_zh.mdMakefileOPCODE.mdREADME.mdREADME.zh-CN.mdSTATUS.mdbench/README.mdbench/arith.lkrbench/arith.luabench/calls.lkrbench/calls.luabench/empty_loop.lkrbench/empty_loop.luabench/fib.lkrbench/fib.luabench/list.lkrbench/map.lkrbench/map.luabench/run_bench.shbench/run_workload_bench.shbench/strcat.lkrbench/strcat.luabench/table.luabench/workloads_business_algorithms.lkbench/workloads_business_algorithms.luacli/Cargo.tomlcli/src/bundler.rscli/src/coverage.rscli/src/diagnostic.rscli/src/main.rscli/src/main_test.rscli/src/paths.rscli/src/pkg.rscli/src/repl.rscli/tests/compile_cli_test.rscli/tests/lkrb_cli_test.rscli/tests/type_system_cli_test.rscore/Cargo.tomlcore/benches/bc32_bench.rscore/benches/bc32_for_range_bench.rscore/benches/bc32_ic_mix_bench.rscore/benches/bc32_while_bench.rscore/benches/bench_main.rscore/benches/call_named_bench.rscore/benches/escape_regions.rscore/benches/index_ic_bench.rscore/benches/scripts_bench.rscore/benches/slots_bench.rscore/benches/vm_micro_bench.rscore/examples/dump_bc.rscore/examples/dump_lkm.rscore/examples/dump_loop.rscore/examples/fib_inner.rscore/examples/test_let.rscore/examples/val_size.rscore/src/ast.rscore/src/ast/ast_test.rscore/src/ast/parser.rscore/src/ast/parser/literals.rscore/src/ast/parser/support.rscore/src/expr.rscore/src/expr/expr_impl.rscore/src/expr/expr_test.rscore/src/expr/match_parsing_test.rscore/src/expr/match_test.rscore/src/expr/pattern_impl.rscore/src/lib.rscore/src/llvm.rscore/src/llvm/backend.rscore/src/llvm/callee_eval.rscore/src/llvm/const_display.rscore/src/llvm/diagnostics.rscore/src/llvm/dynamic_containers.rscore/src/llvm/dynamic_containers/f64_lists.rscore/src/llvm/dynamic_containers/i64_lists.rscore/src/llvm/dynamic_containers/i64_maps.rscore/src/llvm/dynamic_containers/ptr_lists.rscore/src/llvm/dynamic_containers/string_maps.rscore/src/llvm/encoding.rscore/src/llvm/intrinsics.rscore/src/llvm/ir_text.rscore/src/llvm/known_key.rscore/src/llvm/map_mutate.rscore/src/llvm/mod.rscore/src/llvm/options.rscore/src/llvm/output.rscore/src/llvm/output/arg_list_methods.rscore/src/llvm/output/io.rscore/src/llvm/output/iter_methods.rscore/src/llvm/output/list_methods.rscore/src/llvm/output/map_methods.rscore/src/llvm/output/math_methods.rscore/src/llvm/output/object_methods.rscore/src/llvm/output/return_value.rscore/src/llvm/output/string_methods.rscore/src/llvm/passes.rscore/src/llvm/runtime.rscore/src/llvm/scalar.rscore/src/llvm/scalar/block_helpers.rscore/src/llvm/scalar/block_helpers/formatting.rscore/src/llvm/scalar/block_helpers/object_display.rscore/src/llvm/scalar/block_helpers/scalars.rscore/src/llvm/scalar/block_helpers/static_direct.rscore/src/llvm/scalar/block_helpers/symbolic.rscore/src/llvm/scalar/blocks.rscore/src/llvm/scalar/blocks/allocas.rscore/src/llvm/scalar/blocks/arithmetic.rscore/src/llvm/scalar/blocks/asserts.rscore/src/llvm/scalar/blocks/call_args.rscore/src/llvm/scalar/blocks/callees.rscore/src/llvm/scalar/blocks/cells.rscore/src/llvm/scalar/blocks/channel.rscore/src/llvm/scalar/blocks/compare.rscore/src/llvm/scalar/blocks/const_lists.rscore/src/llvm/scalar/blocks/control.rscore/src/llvm/scalar/blocks/direct_print.rscore/src/llvm/scalar/blocks/finalize.rscore/src/llvm/scalar/blocks/get_index.rscore/src/llvm/scalar/blocks/globals.rscore/src/llvm/scalar/blocks/i64_list_methods.rscore/src/llvm/scalar/blocks/iter.rscore/src/llvm/scalar/blocks/len.rscore/src/llvm/scalar/blocks/list_builtin_dispatch.rscore/src/llvm/scalar/blocks/list_direct_calls.rscore/src/llvm/scalar/blocks/list_methods.rscore/src/llvm/scalar/blocks/list_push.rscore/src/llvm/scalar/blocks/map_methods.rscore/src/llvm/scalar/blocks/not.rscore/src/llvm/scalar/blocks/object_methods.rscore/src/llvm/scalar/blocks/returns.rscore/src/llvm/scalar/blocks/runtime_builtins.rscore/src/llvm/scalar/blocks/set_index.rscore/src/llvm/scalar/blocks/string_methods.rscore/src/llvm/scalar/blocks/string_split.rscore/src/llvm/scalar/blocks/values.rscore/src/llvm/scalar/contains.rscore/src/llvm/scalar/contains/int_lists.rscore/src/llvm/scalar/emit.rscore/src/llvm/scalar/facts.rscore/src/llvm/scalar/facts/analysis.rscore/src/llvm/scalar/facts/arg_lists.rscore/src/llvm/scalar/facts/entry.rscore/src/llvm/scalar/facts/list_push.rscore/src/llvm/scalar/facts/list_returns.rscore/src/llvm/scalar/facts/map_methods.rscore/src/llvm/scalar/facts/returns.rscore/src/llvm/scalar/facts/slots.rscore/src/llvm/scalar/facts/string_ops.rscore/src/llvm/scalar/inline.rscore/src/llvm/scalar/kind.rscore/src/llvm/scalar/subfunctions.rscore/src/llvm/straightline_main.rscore/src/llvm/straightline_value.rscore/src/llvm/straightline_value/display.rscore/src/llvm/straightline_value/equality.rscore/src/llvm/straightline_value/maps.rscore/src/llvm/straightline_value/modules.rscore/src/llvm/straightline_value/strings.rscore/src/llvm/subfunction.rscore/src/llvm/subfunction/list.rscore/src/llvm/tests.rscore/src/llvm/tests/basic.rscore/src/llvm/tests/direct_calls.rscore/src/llvm/tests/modules.rscore/src/llvm/tests/objects.rscore/src/llvm/tests/strings.rscore/src/module.rscore/src/op/mod.rscore/src/op/op_test.rscore/src/op/ops.rscore/src/operator.rscore/src/operator/operator_test.rscore/src/operator/syntax.rscore/src/package.rscore/src/perf/mod.rscore/src/perf/scenarios.rscore/src/resolve.rscore/src/resolve/slots.rscore/src/resolve/slots_test.rscore/src/rt.rscore/src/rt/concurrency_test.rscore/src/rt/mod.rscore/src/rt/runtime.rscore/src/stmt.rscore/src/stmt/destructuring_test.rscore/src/stmt/function_test.rscore/src/stmt/if_let_test.rscore/src/stmt/import.rscore/src/stmt/import_parse_test.rscore/src/stmt/rust_function_test.rscore/src/stmt/stmt_impl/ast.rscore/src/stmt/stmt_impl/display.rscore/src/stmt/stmt_impl/type_check.rscore/src/stmt/stmt_parser/bindings.rscore/src/stmt/stmt_parser/control.rscore/src/stmt/stmt_parser/declarations.rscore/src/stmt/stmt_parser/function.rscore/src/stmt/stmt_parser/helpers.rscore/src/stmt/stmt_parser/imports.rscore/src/stmt/stmt_parser/program.rscore/src/stmt/stmt_test.rscore/src/stmt/while_let_test.rscore/src/token.rscore/src/token/error.rscore/src/token/lexer.rscore/src/token/token_test.rscore/src/typ.rscore/src/typ/type_checker.rscore/src/typ/type_checker/expressions.rscore/src/typ/type_checker/expressions/calls.rscore/src/typ/type_checker/tests.rscore/src/typ/type_system.rscore/src/typ/type_system_test.rscore/src/util.rscore/src/util/fast_map.rscore/src/val.rscore/src/val/de.rscore/src/val/de_test.rscore/src/val/meta_method_test.rscore/src/val/methods.rscore/src/val/runtime_model.rscore/src/val/runtime_model/heap.rscore/src/val/val_test.rscore/src/val/values/cache.rscore/src/val/values/convert.rscore/src/val/values/iter.rscore/src/val/values/mod.rscore/src/val/values/ops.rscore/src/val/values/strings.rscore/src/val/values/types.rscore/src/vm.rscore/src/vm/alloc.rscore/src/vm/analysis.rscore/src/vm/analysis_queries.rscore/src/vm/artifact.rscore/src/vm/bc32.rscore/src/vm/bytecode.rscore/src/vm/cache.rscore/src/vm/call_window.rscore/src/vm/compiler.rscore/src/vm/compiler/assign.rscore/src/vm/compiler/builder.rscore/src/vm/compiler/call.rscore/src/vm/compiler/const_eval.rscore/src/vm/compiler/const_maps.rscore/src/vm/compiler/container_lower.rscore/src/vm/compiler/driver.rscore/src/vm/compiler/entry.rscore/src/vm/compiler/expr.rscore/src/vm/compiler/facts.rscore/src/vm/compiler/facts_tests.rscore/src/vm/compiler/for_value_usage.rscore/src/vm/compiler/free_vars.rscore/src/vm/compiler/inline.rscore/src/vm/compiler/loop_consts.rscore/src/vm/compiler/lower_into.rscore/src/vm/compiler/match_expr.rscore/src/vm/compiler/pattern_bind.rscore/src/vm/compiler/pattern_control.rscore/src/vm/compiler/peephole.rscore/src/vm/compiler/range_loop.rscore/src/vm/compiler/ssa/pipeline.rscore/src/vm/compiler/stmt.rscore/src/vm/compiler/support.rscore/src/vm/compiler/tests.rscore/src/vm/compiler/tests/arithmetic.rscore/src/vm/compiler/tests/call_intrinsics.rscore/src/vm/compiler/tests/loops.rscore/src/vm/compiler/tests/patterns.rscore/src/vm/compiler/tests/template.rscore/src/vm/compiler_test.rscore/src/vm/context.rscore/src/vm/context/core_methods.rscore/src/vm/exec.rscore/src/vm/exec/arithmetic.rscore/src/vm/exec/call.rscore/src/vm/exec/callable_ops.rscore/src/vm/exec/cell.rscore/src/vm/exec/const_load.rscore/src/vm/exec/container.rscore/src/vm/exec/container/index.rscore/src/vm/exec/container/set_index.rscore/src/vm/exec/dispatch.rscore/src/vm/exec/exec_tests.rscore/src/vm/exec/exec_tests/basic.rscore/src/vm/exec/exec_tests/calls.rscore/src/vm/exec/exec_tests/container.rscore/src/vm/exec/exec_tests/cross_heap.rscore/src/vm/exec/exec_tests/gc_cell_error.rscore/src/vm/exec/exec_tests/native.rscore/src/vm/exec/gc.rscore/src/vm/exec/globals.rscore/src/vm/exec/handler.rscore/src/vm/exec/imports.rscore/src/vm/exec/named_call.rs
💤 Files with no reviewable changes (33)
- bench/empty_loop.lua
- bench/calls.lkr
- bench/list.lkr
- bench/map.lkr
- LANG.md
- core/benches/bc32_for_range_bench.rs
- bench/map.lua
- bench/empty_loop.lkr
- core/benches/bc32_while_bench.rs
- .github/workflows/perf-dashboard.yml
- core/benches/bc32_ic_mix_bench.rs
- core/benches/slots_bench.rs
- bench/strcat.lkr
- core/benches/bench_main.rs
- core/benches/escape_regions.rs
- bench/fib.lkr
- bench/calls.lua
- bench/arith.lkr
- LANG_zh.md
- bench/run_bench.sh
- core/benches/call_named_bench.rs
- bench/table.lua
- cli/tests/lkrb_cli_test.rs
- bench/arith.lua
- cli/src/bundler.rs
- core/examples/test_let.rs
- bench/fib.lua
- core/benches/scripts_bench.rs
- core/benches/vm_micro_bench.rs
- core/benches/bc32_bench.rs
- bench/strcat.lua
- core/benches/index_ic_bench.rs
- core/examples/val_size.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cloudflare Pages
🧰 Additional context used
🪛 checkmake (0.3.2)
Makefile
[warning] 7-7: Required target "all" is missing from the Makefile.
(minphony)
[warning] 7-7: Required target "clean" is missing from the Makefile.
(minphony)
[warning] 7-7: Required target "test" is missing from the Makefile.
(minphony)
🪛 LanguageTool
STATUS.md
[grammar] ~18-~18: Ensure spelling is correct
Context: ... RUNS=3 EXTRA_RUNS=5 复验中达到 <0.5x vs Lua;但当前 full-suite `RUN_AOT=1 RUNS=1 EXTRA_RUNS...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~39-~39: Ensure spelling is correct
Context: ...bash bench/run_workload_bench.sh ``` - suite:20 项 workload,包含 customer/event/config/tem...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~174-~174: Ensure spelling is correct
Context: ...val;对未注解参数派生局部变量的 compound assignment 类型约束缺口。 -examples/syntax/*.lk` 已在 30 秒单文件 alarm 下复验通过,没有发现本轮 loop/opcode ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~325-~325: Ensure spelling is correct
Context: ...dex/SetIndex增加更直接的 typed map/list helper。 2. 减少RuntimeMapKey构造、heap kind 重复判断和Res...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~326-~326: Ensure spelling is correct
Context: ...timeMapKey构造、heap kind 重复判断和Result` 错误路径污染。 3. 对 string key 和 short-string path 做循环内复用或 ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
OPCODE.md
[uncategorized] ~69-~69: 您的意思是“"不"齐”?
Context: ...sets_top 可在新增 operand-shape opcode 前继续补齐。这样 opcode 空间已变成 128,C 回到 8 bit,并保留 `...
(BU)
[uncategorized] ~84-~84: 您的意思是“"不"走”?
Context: ...atch 也已改成 tight next-op bounds check,避免每步走 code.get(...).map(...)。此前默认 VM 样本 `R...
(BU)
[uncategorized] ~305-~305: 您不可用“是”来表达个形容词。大部分人都平常用“很”来代替“是”。您是不是想表达"很短"?
Context: ...确认 target 是 Map 时,跳过当前 handler 开头“key 是短 List slice 描述”的罕见 probe。该候选不改变 bytecode...
(SHI_ADHECTIVE_ERROR)
[uncategorized] ~358-~358: 您的意思是“"不"齐”?
Context: ...s 和 LLVM scalar lowering。 encoding 稳定后再补齐: - ForPrepI 完整 loop opcode 组合对应 Lu...
(BU)
🪛 markdownlint-cli2 (0.22.1)
README.md
[warning] 45-45: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🪛 Shellcheck (0.11.0)
bench/run_workload_bench.sh
[warning] 20-20: Use single quotes, otherwise this expands now rather than when signalled.
(SC2064)
[warning] 390-390: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 391-391: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 392-392: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 472-472: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 500-500: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 501-501: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 502-502: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
🔇 Additional comments (59)
.gitignore (1)
5-18: LGTM!Cargo.toml (2)
39-41: LGTM!
18-18: 评估toml从 0 → 1 升级的破坏性影响(现有调用点)
Cargo.toml已将toml升级为toml = "1"。仓库内对toml的使用主要集中在:
core/src/val/de.rs:toml::from_str::<toml::Value>(...)解析后按toml::Value::{String,Integer,Float,Boolean,Datetime,Array,Table}分支处理core/src/package.rs:toml::from_str解析 manifest/lockfile;toml::to_string_pretty序列化写回core/src/llvm/output.rs:基于toml::Value分支,并使用value.parse::<toml::Table>()需要重点确认在
toml1 下上述解析/序列化路径(尤其是Datetime/Table/数组)与现有逻辑行为一致,并通过构建与测试覆盖 manifest/lockfile 读写及配置解析流程。Makefile (2)
20-22: LGTM!
17-18: 确认debug-lsp-ext目标依赖脚本已存在:无需补充添加
debug-lsp-ext目标调用的./scripts/debug-vscode-lsp.sh在仓库中已存在(且为可执行文件),因此该依赖缺失的问题不成立。core/Cargo.toml (3)
2-10: LGTM!
16-16: LGTM!
33-36: LGTM!OPCODE.md (1)
1-381: LGTM!README.md (2)
57-74: LGTM!
78-90: LGTM!README.zh-CN.md (2)
46-62: LGTM!
66-78: LGTM!STATUS.md (1)
1-381: LGTM!bench/README.md (1)
1-652: LGTM!bench/workloads_business_algorithms.lk (1)
1-630: LGTM!bench/workloads_business_algorithms.lua (1)
1-612: LGTM!cli/src/coverage.rs (1)
1-156: LGTM!cli/src/diagnostic.rs (1)
1-47: LGTM!cli/src/main.rs (3)
570-617: LGTM!
648-684: LGTM!
713-865: LGTM!cli/src/paths.rs (3)
15-27: LGTM!
33-50: LGTM!
52-207: LGTM!cli/src/pkg.rs (3)
61-95: LGTM!
97-131: LGTM!
173-210: LGTM!cli/src/main_test.rs (1)
156-247: LGTM!cli/src/repl.rs (5)
4-13: LGTM!
112-124: LGTM!
209-240: LGTM!
219-219: LGTM!Also applies to: 229-229
245-252: LGTM!cli/tests/compile_cli_test.rs (5)
7-39: LGTM!
41-107: LGTM!
109-905: LLVM 测试中的工具路径设置是刻意为之。多个 LLVM 测试(如第 141、252、436 行等)将
RUSTC或LK_CLANG环境变量设置为不存在的路径。这是刻意设计,用于强制特定的代码路径执行,避免依赖外部工具。这种做法在集成测试中是合理的。
163-217: LGTM!
987-1029: LGTM!cli/tests/type_system_cli_test.rs (1)
11-11: LGTM!Also applies to: 21-21
core/src/ast/ast_test.rs (1)
1-595: LGTM!core/src/ast/parser.rs (1)
1-1332: LGTM!core/src/expr/match_test.rs (1)
1-196: LGTM!core/src/lib.rs (1)
1-21: LGTM!core/src/llvm/backend.rs (1)
1-83: LGTM!core/src/expr.rs (1)
2-2: LGTM!core/examples/dump_bc.rs (1)
1-66: LGTM!core/examples/fib_inner.rs (1)
1-19: LGTM!core/src/llvm.rs (1)
1-30: LGTM!core/src/expr/expr_impl.rs (4)
603-603: 确认:表达式级块不进行常量折叠
Expr::Block在常量折叠时直接返回自身,不对内部语句进行折叠。这是正确的设计,因为语句级的折叠需要执行上下文,在表达式折叠阶段无法安全进行。LGTM!
440-450: 确认:访问表达式的折叠保留策略正确当字段为字符串字面量时,代码有意保留
Access结构而不将其折叠为具体值。注释清楚地解释了原因:这样可以让后续的方法调用语法(如foo.bar())能够正确拦截并进行元方法分发。如果将foo.bar折叠为具体值(如Int),则后续调用会尝试调用非函数值而失败。这是一个深思熟虑的设计决策。
LGTM!
800-840: 字符串拼接优化实现得当
fold_literal_add中对字符串拼接的处理使用了itoa::Buffer和ryu::Buffer进行高效的整数/浮点数格式化,避免了format!宏的开销。代码覆盖了所有字符串与数值类型的组合,实现完整且高效。LGTM!
33-49: 序列化移除影响:代码库内未见对相关类型的直接 serde 依赖,但仍需补做类型推断场景排查在
core/src/expr/expr_impl.rs(含后续相应区段)对应的Expr/Pattern/MatchArm/SelectCase/SelectPattern上,core/src/expr/*未发现Serialize/Deserialize派生或serde::Serialize/serde::Deserializetrait bound;全仓core/src里也未发现serde_json/bincode/ron/toml的显式序列化调用与这些类型名相邻的用法。
仍建议人工再扫一遍serde_json::to_*/bincode::serialize等调用点,确认实参的静态类型是否为上述类型(类型推断时类型名可能不会出现在调用文本中),并评估对外部 API 的兼容性与迁移说明。core/src/expr/pattern_impl.rs (1)
1-59: LGTM!core/examples/dump_lkm.rs (1)
1-17: LGTM!core/examples/dump_loop.rs (1)
1-25: LGTM!core/src/expr/expr_test.rs (2)
295-347: 测试基础设施迁移设计合理新的测试辅助函数将表达式测试从直接求值(
eval_with_ctx)迁移到完整脚本执行(execute_source)。这种方式更接近实际使用场景,且辅助函数expect、expect_env、panic_env和panic提供了清晰的测试意图表达。LGTM!
417-431: 常量折叠验证测试覆盖得当测试用例正确验证了模板字符串的常量折叠行为:纯常量模板被折叠为单一
Expr::Literal,而包含变量插值的模板保持为Expr::TemplateString。这确保了常量折叠优化不会影响动态插值的语义。LGTM!
core/src/expr/match_parsing_test.rs (1)
1-254: LGTM!
| toml = { workspace = true } | ||
| clap = { version = "4", features = ["derive"] } | ||
| rustyline = "17" | ||
| rustyline = "18" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 搜索 rustyline 的使用
rg -n --type=rust 'use.*rustyline' cli/src/ -A2 -B1
# 查找可能受影响的 Editor/Config API
rg -n --type=rust 'Editor|ReadlineError|Config' cli/src/repl.rs -C2Repository: lollipopkit/lk
Length of output: 893
🌐 Web query:
What are the breaking changes between rustyline 17 and 18?
💡 Result:
The transition from rustyline 17 to 18 (released March 29, 2026) introduced several significant changes, primarily focused on internal refactoring, dependency updates, and improved terminal handling [1]. While there is no singular dedicated "breaking changes" document, the key areas of impact that likely require user code adjustments include: New Prompt Trait: A major addition is the introduction of the Prompt trait [1]. This trait is used for styling the prompt, which may require updates to existing implementations that manage or display prompts [1]. Dependency Updates: Rustyline 18 significantly updated its underlying dependencies, which may necessitate compatibility checks for projects using these libraries alongside rustyline [1]: - nix updated to 0.31 [1]. - signal-hook updated to 0.4 [1]. - rand updated to 0.10 [1]. - skim updated to 3.3.0 [1]. - radix_trie updated to 0.3 [1]. Windows Terminal Behavior: There were specific changes to how prompts are styled and handled on Windows to avoid conflicts, particularly regarding styled prompts [1]. Internal Refactorings: - Signal Handling: The internal mechanism for signal handling was refactored, and signal handlers are now only installed when the library is actively reading input [1]. - File Locking: The crate moved from the fd-lock dependency to using standard library File::lock functionality [1]. - Partial Repaint: Support for minimal/partial repainting was introduced, which might affect custom UI components if they rely on full-line refreshing behavior [1]. To migrate from 17 to 18, users should review their use of the Prompt trait, verify compatibility with the updated dependency versions listed above, and test signal handling if their application relies on specific low-level terminal behaviors [1]. You can view the full list of changes in the official release notes [1].
Citations:
检查 rustyline 17→18 升级对 REPL 的影响
- 目前仅在
cli/src/repl.rs中使用rustyline::{DefaultEditor, error::ReadlineError},并调用DefaultEditor::new()?、处理ReadlineError::Interrupted/ReadlineError::Eof;重点核对DefaultEditor::new()的签名与ReadlineError相关变更是否与 rustyline 18 匹配(枚举项/错误类型是否有改动)。 - rustyline 18 引入
Prompttrait:如代码存在自定义提示/渲染逻辑,需要确保已按新机制适配;同时核对中断/EOF 对应的终端/信号行为是否仍符合当前分支逻辑。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cli/Cargo.toml` at line 32, 升级 rustyline 到 18 可能改变了 DefaultEditor::new
的签名、ReadlineError 枚举项和引入了 Prompt trait;在 cli/src/repl.rs 中检查并更新对
DefaultEditor::new() 的调用(确保错误处理或返回类型匹配新签名),核对并更新对 ReadlineError 的匹配分支(包括
Interrupted/Eof 名称或模块路径是否变动),并如果你实现或自定义提示/渲染逻辑,改用 rustyline 18 的 Prompt trait
实现或其新的提示 API;修复后运行 REPL 并验证中断/EOF 行为与之前一致。
| fn vm_profile_line(metrics: VmRuntimeMetrics) -> String { | ||
| format!( | ||
| "VM profile: opcode_steps={} top_opcodes={} write_sources={} index_keys={} calls={} branches={} typed_branches={} containers={} list_ops={} map_ops={} string_ops={} val_clones={} heap_clones={} copy_policy_heap_clones={} register_copy_heap_clones={} local_copy_heap_clones={} local_load_heap_clones={} local_store_heap_clones={} const_load_heap_clones={} call_arg_heap_clones={} container_copy_heap_clones={}", | ||
| metrics.opcode_steps, | ||
| top_opcode_profile(&metrics), | ||
| top_register_write_source_profile(&metrics), | ||
| top_index_key_profile(&metrics), | ||
| metrics.call_ops, | ||
| metrics.branch_ops, | ||
| metrics.typed_branch_ops, | ||
| metrics.container_ops, | ||
| metrics.list_ops, | ||
| metrics.map_ops, | ||
| metrics.string_ops, | ||
| metrics.copy_policy_heap_clones, | ||
| metrics.copy_policy_heap_clones, | ||
| metrics.copy_policy_heap_clones, | ||
| metrics.register_copy_heap_clones, | ||
| metrics.local_copy_heap_clones, | ||
| metrics.local_load_heap_clones, | ||
| metrics.local_store_heap_clones, | ||
| metrics.const_load_heap_clones, | ||
| metrics.call_arg_heap_clones, | ||
| metrics.container_copy_heap_clones | ||
| ) | ||
| } |
There was a problem hiding this comment.
格式化字符串中存在重复/不一致的字段赋值。
Lines 251-260 中,多个不同的格式化字段都使用了 metrics.copy_policy_heap_clones:
val_clones={}→metrics.copy_policy_heap_clonesheap_clones={}→metrics.copy_policy_heap_clonescopy_policy_heap_clones={}→metrics.copy_policy_heap_clones
这很可能是复制粘贴错误。请检查这些字段应该对应哪些实际的 metrics 字段。例如,val_clones 可能应该聚合多个克隆计数器,或者使用其他独立的 metrics 字段。
🐛 建议核对正确的字段映射
请根据 VmRuntimeMetrics 的实际字段定义,确保每个格式化输出字段都使用了正确的 metric 值。可能需要类似这样的修正:
metrics.opcode_steps,
top_opcode_profile(&metrics),
top_register_write_source_profile(&metrics),
top_index_key_profile(&metrics),
metrics.call_ops,
metrics.branch_ops,
metrics.typed_branch_ops,
metrics.container_ops,
metrics.list_ops,
metrics.map_ops,
metrics.string_ops,
- metrics.copy_policy_heap_clones,
- metrics.copy_policy_heap_clones,
+ // TODO: 确认 val_clones 应该使用哪个字段
+ // TODO: 确认 heap_clones 应该使用哪个字段
metrics.copy_policy_heap_clones,
metrics.register_copy_heap_clones,
metrics.local_copy_heap_clones,
metrics.local_load_heap_clones,
metrics.local_store_heap_clones,
metrics.const_load_heap_clones,
metrics.call_arg_heap_clones,
metrics.container_copy_heap_clones🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cli/src/main.rs` around lines 237 - 262, In vm_profile_line the format
string's placeholders for val_clones, heap_clones and copy_policy_heap_clones
are all passed metrics.copy_policy_heap_clones (a copy-paste bug); open the
VmRuntimeMetrics struct, identify the correct fields (e.g. metrics.val_clones
and metrics.heap_clones if present) and replace the duplicate arguments so the
nth argument matches the nth {} in the format string (keep top_opcode_profile,
top_register_write_source_profile, top_index_key_profile and the other metrics
in the same order). If val_clones should be an aggregate, compute it before the
format call and pass that value instead. Ensure the final argument list length
and order exactly match the placeholders in vm_profile_line.
Deploying lk-lang with
|
| Latest commit: |
6218d23
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://75a668b4.lk-d8q.pages.dev |
| Branch Preview URL: | https://dev.lk-d8q.pages.dev |
…trait prescan 契约锁 review PR #17 发现的三项修复: 1. **chan.rs 持锁 raise → 永久死锁**(最重):raise 走 longjmp 跳过 Rust drop,存活的 MutexGuard 永不解锁。两处: - channel() 的 "Channel not found" raise 时 registry 全局锁 guard 还在 match 临时值里活着(**当前可达**:try{recv(999)}catch 后 一切 channel 操作死锁)→ 先 cloned() 出 Option 再 raise; - select send 臂在持 ChanInner state 锁时调用可 raise 的 own() (当前 tag 集下 latent)→ armed send 载荷进循环前预深拷, kind 预验证,循环内 fallback 改 unreachable。 blocking send/recv 本就遵守 drop-before-raise 纪律——正是这纪律 证明这两处是疏漏。纪律成文进 CLAUDE.md lkrt 段。 2. **trait prescan 形状契约锁**(J1 计划欠账):examples 差分对 unsupported 静默 skip,compiler 改 impl 注册序列发射形状会静默 丢 trait 覆盖。新 differential_trait_dispatch_contract 走 run_differential(硬性要求 lower 成功)——形状漂移即红。 3. **CLAUDE.md**:lkrt 边界规则补 dev-dep lk-core(仅 order- conformance 测试)例外条款 + 锁跨 raise 硬规则。 新差分 ×3:trait 契约、chan 未知 id catch 后可用、select 闭 send catch 后可用(2/3 是死锁回归测试,修前会挂死)。 留档不做(review findings #3/#5/#6):硬编码名单收拢进单表、 fixpoint 快照 clone 优化、select spin-poll 换 Condvar 多路等待。 门禁:50/51 · 差分 12/12 · workspace 0 · fuzz 150 · -D warnings all-features 0 · clippy/fmt 0 · bench 见下
Summary
Verification
Notes
Summary by CodeRabbit
发布说明
新功能
文档
杂项