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>
27 lines
851 B
Plaintext
27 lines
851 B
Plaintext
// Phase 285 P2: WeakRef upgrade failure test (explicit drop + null observation)
|
||
// SSOT: docs/reference/language/lifecycle.md - weak_to_strong() failure → null
|
||
//
|
||
// Test: weak_to_strong() fails after explicit drop (x = null)
|
||
// Note: Uses explicit drop instead of block scope (block scope drop conformance is separate task)
|
||
// Expected: exit 1 (weak_to_strong returns null as expected)
|
||
// Phase 285 P2.1: FIXED with KeepAlive instruction
|
||
|
||
box SomeBox {
|
||
x
|
||
}
|
||
|
||
static box Main {
|
||
main() {
|
||
local x = new SomeBox()
|
||
x.x = 123
|
||
local w = weak x
|
||
x = null // 明示的に strong を切る
|
||
local y = w.weak_to_strong() // 失敗して null
|
||
if y == null {
|
||
return 1 // 期待通り(weak_to_strong 失敗)
|
||
} else {
|
||
return 0 // 予期しない成功
|
||
}
|
||
}
|
||
}
|