Files
hakorune/docs/development/current/main/phases/phase-285/README.md
tomoaki cc8b27a1aa feat(weak): Phase 285A1 - Weak Field Contract (Strict Type Enforcement)
Remove automatic WeakNew conversion and enforce strict compile-time type
checking for weak field assignments. Only 3 assignment types allowed:
1. Result of weak(x) call (WeakRef type)
2. Existing WeakRef variable (e.g., me.parent = other.parent)
3. Void/null (clear operation)

**Implementation**:
- Added MirType::WeakRef to type system (src/mir/types.rs)
- Track WeakRef type in emit_weak_new() even in pure mode
- Weak field reads return WeakRef without auto-upgrade
- Removed automatic WeakNew conversion from field writes
- Implemented check_weak_field_assignment() with actionable errors
- Fixed null literal type tracking (Phase 285A1.1: Unknown → Void)

**Testing**:
- 5 test fixtures (3 OK, 2 NG cases) - all passing
- Smoke test: phase285_weak_field_vm.sh
- Error messages guide users to use weak() or null

**Documentation**:
- Updated lifecycle.md SSOT with weak field contract

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 03:17:30 +09:00

4.9 KiB
Raw Blame History

Phase 285: Box lifecycle / weakref / finalization / GC conformance

Status: Planned (design-first)

Goal

Box の生存期間(強参照/弱参照/解放/最終化/GCを SSOT として固定し、移行期間でも意味論が割れない状態にする。

Language-level SSOT:

  • Lifecycle/weak/fini/GC policy: docs/reference/language/lifecycle.md
  • Truthiness + null/void: docs/reference/language/types.md

This Phase document is not the language SSOT; it tracks implementation status, backend gaps, and acceptance criteria.

Why now

  • JoinIR/Plan/compose の収束が進むほど、実行時の “値の寿命” の揺れが目立つ。
  • weakref/finalization は「実装が仕様」になりやすく、後から直すコストが最大級。
  • LLVM harness 側は未対応の可能性が高く、差分を “仕様として明文化” しないと再現/調査が難しい。

SSOT References (current code)

  • weakref の値表現: src/value.rsNyashValue::WeakBox
  • finalization: src/finalization.rs
  • Box trait: src/box_trait.rsSharedNyashBox = Arc<dyn NyashBox>
  • Scope tracking: src/scope_tracker.rsBox の登録/スコープ)

Snapshot今わかっていること

  • weakref は Weak<Mutex<dyn NyashBox>> で保持される(NyashValue::WeakBox
  • WeakBoxto_string()weak_to_strong() を試み、WeakRef(null) 表示になりうる(観測可能)
  • src/value.rs に weakref の drop 挙動を固定する unit test がある(test_weak_reference_drop

Responsibility Mapどこが仕様を決めるか

  • SSOT意味: docs/reference/language/*言語レベルのSSOT
  • Conformance: Rust VM / LLVM harness / WASM / JIT など各バックエンド実装
  • 観測の固定: fixture/smokePhase 285 P2 で作る)

用語P0で固定する

  • Strong reference: 所有参照(Arc 等で Box を保持)
  • Weak reference: 非所有参照(Weak / weak_to_strong() が失敗しうる)
  • Weak-to-strong: weak → strong の昇格(成功/失敗が意味論)
  • Roots: 解放/GC から保護される参照集合stack/local/global/handle/plugin
  • Finalizer: 解放に伴う最終化処理(もし存在するなら)

P0 decisions (docs-only)

  • Weak の観測は weak_to_strong() で行い、失敗値は null= runtime Void の別名)。
  • cleanupStage3 block-postfixが「出口で必ず走る」決定的 cleanup を保証する(catch の有無に関係なく、常に実行)。
  • GC は意味論ではなく補助GC off で cycle はリークしうる)。
  • ByRef (RefGet/RefSet) は non-owning / non-escaping寿命・弱参照・GC の道具にしない)。

RUNBOOK caveat (implementation reality)

The runbook assumes WeakRef infrastructure exists in the VM and lowering. If any of the following are missing, treat weak smokes as unsupported and scope to exit-time leak report first:

  • weak(x) parse/lower
  • VM handler for MIR WeakRef/WeakNew/WeakLoad
  • language-surface weak_to_strong() on WeakRef

Questions to Answer (P0/P1)

  • weakref の “生存判定” は何で観測できるか(toString / is_alive / weak_to_strong API など)
  • finalizer は存在するか / いつ発火するかdrop 時GC 時?明示 API
  • finalizer 内での禁止事項再入、例外、I/O、allocationをどうするか
  • LLVM harness の扱い(現状未対応なら “未対応として SSOT 化”)

Scope (proposed)

P0docs-only

  • 用語の固定strong/weak/roots/finalizer/collection
  • 仕様の固定weakref の weak_to_strong 成否、finalizer の発火条件、禁止事項)
  • “LLVM harness の扱い” を明文化(未対応なら未対応として SSOT に書く)

P1investigation

  • Rust VM の現状実装の棚卸し(どこで roots が形成され、どこで解放/最終化されるか)
  • LLVM harness の現状調査(弱参照/GC が無い場合は差分として記録)

P2smoke

  • weakref の最小 fixture/smoke を作り、挙動を固定する
    • VM: stdout/exit code で固定
    • LLVM: 未対応なら “スキップ理由” を smoke で明示

Non-goals

  • GC アルゴリズム刷新RC→tracing 等の設計変更)
  • LLVM harness に同等機能を “一気に” 実装(差分の記録→段階導入を優先)

Acceptance criteria (P2+)

  • VM と LLVM で、weak が仕様通り動作する(weak_to_strong() 成功/失敗が一致、失敗は null)。
  • 強参照サイクルを意図的に作ったとき、GC off なら)回収されないことが観測できる。
  • 終了時に「強参照が残っている root」をデバッグ出力できるdefault-off の診断フラグ)。
    • これは意味論ではなく診断であり、ON/OFF でプログラムの意味を変えない。