Add KeepAlive instruction to fix hidden root problem where x = null
doesn't properly drop the strong reference.
Key changes:
- Add KeepAlive { values, drop_after } instruction to MIR
- Emit KeepAlive[drop=true] in build_assignment() before variable overwrite
- Emit KeepAlive[drop=false] in pop_lexical_scope() at scope end
- VM handler: when drop_after=true, remove ALL ValueIds pointing to
the same Arc (handles SSA Copy chains)
Test results:
- weak_upgrade_fail: exit 1 ✅ (weak_to_strong returns null after x=null)
- weak_basic: exit 2 ✅ (weak_to_strong succeeds while x alive)
- quick smoke: 154/154 PASS ✅🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>