diff --git a/docs/private b/docs/private index e54d615e..118726f6 160000 --- a/docs/private +++ b/docs/private @@ -1 +1 @@ -Subproject commit e54d615e5fb615025d39ca4f7bec52ce6f8bcf6c +Subproject commit 118726f606f6d565c8923e7f58db82f8562985cd diff --git a/src/mir/builder/builder_calls.rs b/src/mir/builder/builder_calls.rs index a7e12bb0..36ade7d8 100644 --- a/src/mir/builder/builder_calls.rs +++ b/src/mir/builder/builder_calls.rs @@ -860,18 +860,6 @@ impl super::MirBuilder { params: Vec, body: Vec, ) -> Result<(), String> { - // 🎯 箱理論: コンテキスト分離(開始) - // compilation_contextがある場合、その内容を既存のフィールドとswap - // これにより、既存のコードを変更せずにコンテキスト分離を実現 - let context_active = self.compilation_context.is_some(); - if context_active { - if let Some(ref mut ctx) = self.compilation_context { - std::mem::swap(&mut self.variable_map, &mut ctx.variable_map); - std::mem::swap(&mut self.value_origin_newbox, &mut ctx.value_origin_newbox); - std::mem::swap(&mut self.value_types, &mut ctx.value_types); - } - } - // Derive static box context from function name prefix, e.g., "BoxName.method/N" let saved_static_ctx = self.current_static_box.clone(); if let Some(pos) = func_name.find('.') { @@ -880,6 +868,26 @@ impl super::MirBuilder { self.current_static_box = Some(box_name.to_string()); } } + + // 🎯 箱理論: BoxCompilationContext と saved_var_map をモード別に管理 + // context_active = true の場合(BoxCompilationContext mode): + // - clear() で完全独立化(各メソッドが汚染されない) + // - swap は不要(累積バグの原因) + // context_active = false の場合(Legacy mode): + // - saved_var_map に退避して空から開始し、終了時に復元 + let context_active = self.compilation_context.is_some(); + let saved_var_map = if !context_active { + Some(std::mem::take(&mut self.variable_map)) + } else { + None + }; + if context_active { + // 🎯 箱理論: 完全独立化(clear のみ、swap 不要) + self.variable_map.clear(); + self.value_origin_newbox.clear(); + self.value_types.clear(); + } + let signature = function_lowering::prepare_static_method_signature( func_name, ¶ms, @@ -890,7 +898,6 @@ impl super::MirBuilder { let function = super::MirFunction::new(signature, entry); let saved_function = self.current_function.take(); let saved_block = self.current_block.take(); - let saved_var_map = std::mem::take(&mut self.variable_map); self.current_function = Some(function); self.current_block = Some(entry); self.ensure_block_exists(entry)?; @@ -952,20 +959,22 @@ impl super::MirBuilder { } self.current_function = saved_function; self.current_block = saved_block; - self.variable_map = saved_var_map; + + // 🎯 箱理論: モード別に状態を復元 + if context_active { + // 🎯 BoxCompilationContext mode: clear のみ(次回も完全独立) + // swap は不要(累積バグを防ぐ) + self.variable_map.clear(); + self.value_origin_newbox.clear(); + self.value_types.clear(); + } else if let Some(saved) = saved_var_map { + // 従来モード: Main.main 側の variable_map を元に戻す + self.variable_map = saved; + } + // Restore static box context self.current_static_box = saved_static_ctx; - // 🎯 箱理論: コンテキスト分離(終了) - // swap backでコンテキストに変更を保存 - if context_active { - if let Some(ref mut ctx) = self.compilation_context { - std::mem::swap(&mut self.variable_map, &mut ctx.variable_map); - std::mem::swap(&mut self.value_origin_newbox, &mut ctx.value_origin_newbox); - std::mem::swap(&mut self.value_types, &mut ctx.value_types); - } - } - Ok(()) } } diff --git a/src/tests/mir_stage1_using_resolver_verify.rs b/src/tests/mir_stage1_using_resolver_verify.rs index 6e1e7334..ef026ba1 100644 --- a/src/tests/mir_stage1_using_resolver_verify.rs +++ b/src/tests/mir_stage1_using_resolver_verify.rs @@ -70,7 +70,7 @@ static box Stage1UsingResolverMini { /// Verify MIR/SSA for ParserBox.parse_program2 in isolation by compiling a small wrapper. #[test] -fn mir_parserbox_parse_program2_verifies() { +fn mir_parserbox_parse_program2_harness_parses_minimal_source() { // Minimal wrapper that brings ParserBox into scope and calls parse_program2. let src = r#" using lang.compiler.parser.parser_box as ParserBox @@ -84,15 +84,16 @@ static box ParserBoxHarness { } "#; - let ast: ASTNode = NyashParser::parse_from_string(src).expect("parse ok"); + // Stage‑3 構文キーワード `local` を含む最小ソースを ParserBoxHarness でパースする + let harness_ast: ASTNode = NyashParser::parse_from_string(src).expect("parse ok"); let mut mc = MirCompiler::with_options(false); - let cr = mc.compile(ast).expect("compile"); + let cr = mc.compile(harness_ast).expect("compile"); let mut verifier = MirVerifier::new(); if let Err(errors) = verifier.verify_module(&cr.module) { for e in &errors { eprintln!("[mir-verify] {}", e); } - panic!("MIR verification failed for ParserBoxHarness.parse_program2"); + panic!("MIR verification failed for ParserBoxHarness"); } }