feat(joinir): Phase 186 LoopBuilder Hard Freeze - Add access control guard

Add environment variable check at LoopBuilder fallback point (control_flow.rs:60).
LoopBuilder is now only accessible when NYASH_LEGACY_LOOPBUILDER=1 is explicitly set.

Changes:
- control_flow.rs: Add env guard before LoopBuilder instantiation
- Default behavior: JoinIR-only (LoopBuilder disabled)
- Legacy mode: NYASH_LEGACY_LOOPBUILDER=1 enables fallback
- Error message: Clear hint about legacy mode opt-in

Testing:
- legacy OFF (NYASH_LEGACY_LOOPBUILDER=0): Error (frozen)
- legacy ON (NYASH_LEGACY_LOOPBUILDER=1): Success (allowed)

🤖 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-04 23:35:33 +09:00
parent c2f524bb26
commit 30f94c9550

View File

@ -56,7 +56,18 @@ impl super::MirBuilder {
eprintln!("[cf_loop] CALLED from somewhere"); eprintln!("[cf_loop] CALLED from somewhere");
eprintln!("[cf_loop] Current stack (simulated): check build_statement vs build_expression_impl"); eprintln!("[cf_loop] Current stack (simulated): check build_statement vs build_expression_impl");
} }
// Delegate to LoopBuilder for consistent handling
// Phase 186: LoopBuilder Hard Freeze - Require explicit legacy mode opt-in
if !crate::config::env::joinir_dev::legacy_loopbuilder_enabled() {
return Err(format!(
"[joinir/freeze] Loop lowering failed: JoinIR does not support this pattern, and LoopBuilder is disabled.\n\
Function: {}\n\
Hint: Set NYASH_LEGACY_LOOPBUILDER=1 to enable legacy path (dev-only)",
self.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("<unknown>")
));
}
// Delegate to LoopBuilder for consistent handling (legacy path only)
let mut loop_builder = crate::mir::loop_builder::LoopBuilder::new(self); let mut loop_builder = crate::mir::loop_builder::LoopBuilder::new(self);
loop_builder.build_loop(condition, body) loop_builder.build_loop(condition, body)
} }