feat(joinir): Phase 183 LoopBodyLocal role separation + test fixes

Phase 183 Implementation:
- Added is_var_used_in_condition() helper for AST variable detection
- Implemented LoopBodyLocal filtering in TrimLoopLowerer
- Created 4 test files for P1/P2 patterns
- Added 5 unit tests for variable detection

Test Fixes:
- Fixed test_is_outer_scope_variable_pinned (BasicBlockId import)
- Fixed test_pattern2_accepts_loop_param_only (literal node usage)

Refactoring:
- Unified pattern detection documentation
- Consolidated CarrierInfo initialization
- Documented LoopScopeShape construction paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-08 23:43:26 +09:00
parent a3df5ecc7a
commit 440f8646b1
66 changed files with 279 additions and 183 deletions

View File

@ -405,10 +405,10 @@ impl MirInterpreter {
// Plugin Box methods (slot >= 1000)
(_, slot) if slot >= 1000 => {
if let VMValue::BoxRef(bx) = receiver {
if let Some(p) = bx.as_any().downcast_ref::<crate::runtime::plugin_loader_v2::PluginBoxV2>() {
if let Some(_p) = bx.as_any().downcast_ref::<crate::runtime::plugin_loader_v2::PluginBoxV2>() {
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
let host = host.read().unwrap();
let argv = self.load_args_as_boxes(args)?;
let _host = host.read().unwrap();
let _argv = self.load_args_as_boxes(args)?;
// Get method name from slot (reverse lookup would be needed in production)
// For now, fall back to old path
return Err(self.err_with_context(
@ -474,7 +474,7 @@ impl MirInterpreter {
// StringBox special methods (is_space, is_alpha)
if box_ref.type_name() == "StringBox" {
let s_box = box_ref.to_string_box();
let s = s_box.value;
let _s = s_box.value;
match method {
"is_space" => {
if let Some(arg_id) = args.get(0) {