Files
hakorune/src/mir/builder/weak_field_validator.rs
tomoaki 2da730de35 refactor(cleanup): Phase 285A1 Post-Implementation Cleanup
Code quality improvements after Phase 285A1 implementation:

**Task 1: Dead Code Cleanup**
- Removed unnecessary #[allow(dead_code)] from emit_weak_load()
- Function is actively used in weak_to_strong() method handler

**Task 2: Unused Import Removal (cargo fix)**
- edgecfg/api/mod.rs: Removed seq, if_, loop_, cleanup, verify_frag_invariants
- pattern3.rs: Removed BinaryOperator
- pattern2/api/mod.rs: Removed PromoteStepResult
- jump.rs: Removed EffectMask, Span
- Result: 6 unused imports eliminated

**Task 3: Deprecated Pattern Removal**
- Fixed 4 PlanKind::LoopWithPost deprecated warnings
- Updated to Phase 142 P0 architecture (statement-level normalization)
- Files: normalized_shadow_suffix_router_box.rs, routing.rs,
  execute_box.rs, plan.rs
- Removed 2 deprecated tests: test_loop_with_post_*

**Task 4: WeakFieldValidatorBox Boxification**
- Extracted weak field validation logic into dedicated Box
- New file: src/mir/builder/weak_field_validator.rs (147 lines)
- fields.rs: 277 → 237 lines (-40 lines, -14.4%)
- Added 5 unit tests for validation logic
- Follows Phase 33 boxification principles (single responsibility,
  testability, reusability)

**Metrics**:
- Code reduction: -40 lines in fields.rs
- Test coverage: +5 unit tests
- Warnings fixed: 4 deprecated warnings
- Imports cleaned: 6 unused imports

🤖 Generated with Claude Code

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

147 lines
5.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Phase 285A1: Weak Field Contract Validator
//
// Responsibility: weak field への代入時の型契約検証
// - 読み込み時の型注釈WeakRef として扱う)
// - 書き込み時の型検証3つの許可ケース
use super::type_context::TypeContext;
use super::ValueId;
use crate::mir::types::MirType;
/// Phase 285A1: Weak Field Contract Validator Box
///
/// 単一責任: weak field の契約検証のみ
/// - 読み込み時: WeakRef 型注釈
/// - 書き込み時: 型契約検証WeakRef/Void のみ許可)
pub(super) struct WeakFieldValidatorBox;
impl WeakFieldValidatorBox {
/// Weak field 読み込み時の型注釈を追加
///
/// Phase 285A1: weak field の読み込み結果は WeakRef 型として扱う(自動昇格なし)
///
/// # Arguments
/// - `type_ctx`: 型コンテキストvalue_types に WeakRef を記録)
/// - `dst`: 読み込み結果の ValueId
pub(super) fn annotate_read_result(
type_ctx: &mut TypeContext,
dst: ValueId,
) {
// Phase 285A1: Mark the result as WeakRef type
type_ctx.value_types.insert(dst, MirType::WeakRef);
}
/// Weak field への代入を検証3つの許可ケース
///
/// Phase 285A1 Fail-Fast 契約:
/// - **許可**: WeakRef (weak() または weak field 読み込み)
/// - **許可**: Void (クリア操作)
/// - **禁止**: BoxRef (weak() なしの Box)
/// - **禁止**: プリミティブ型
/// - **禁止**: 型追跡されていない値
///
/// # Arguments
/// - `value_type`: 代入する値の型情報
/// - `box_name`: フィールドを持つ Box 名(エラーメッセージ用)
/// - `field_name`: weak field 名(エラーメッセージ用)
///
/// # Returns
/// - `Ok(())`: 代入が許可される場合
/// - `Err(String)`: 代入が禁止される場合Fail-Fast
///
/// # Example Error Messages
/// ```text
/// Cannot assign Box (StringBox) to weak field 'Node.next'.
/// Use weak(...) to create weak reference: me.next = weak(value)
/// ```
pub(super) fn validate_assignment(
value_type: Option<&MirType>,
box_name: &str,
field_name: &str,
) -> Result<(), String> {
match value_type {
// Case 1: WeakRef allowed (from weak() or weak field read)
Some(MirType::WeakRef) => Ok(()),
// Case 2: Void allowed (clear operation)
Some(MirType::Void) => Ok(()),
// Forbidden: None/Unknown (型追跡漏れ防止 - Fail-Fast)
None => Err(format!(
"Cannot assign untracked value to weak field '{}.{}'. Use weak(...) or Void explicitly.",
box_name, field_name
)),
// Forbidden: BoxRef (強参照を直接代入 - Fail-Fast)
Some(MirType::Box(box_type)) => Err(format!(
"Cannot assign Box ({}) to weak field '{}.{}'. Use weak(...) to create weak reference: me.{} = weak(value)",
box_type, box_name, field_name, field_name
)),
// Forbidden: Primitives and others (Fail-Fast)
Some(other_type) => Err(format!(
"Cannot assign {:?} to weak field '{}.{}'. Weak fields require WeakRef type. Use weak(...) or Void.",
other_type, box_name, field_name
)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_weakref_allowed() {
let result = WeakFieldValidatorBox::validate_assignment(
Some(&MirType::WeakRef),
"Node",
"next",
);
assert!(result.is_ok(), "WeakRef should be allowed");
}
#[test]
fn test_validate_void_allowed() {
let result = WeakFieldValidatorBox::validate_assignment(
Some(&MirType::Void),
"Node",
"next",
);
assert!(result.is_ok(), "Void should be allowed");
}
#[test]
fn test_validate_boxref_forbidden() {
let result = WeakFieldValidatorBox::validate_assignment(
Some(&MirType::Box("StringBox".to_string())),
"Node",
"next",
);
assert!(result.is_err(), "BoxRef should be forbidden");
assert!(result.unwrap_err().contains("Use weak(...)"));
}
#[test]
fn test_validate_untracked_forbidden() {
let result = WeakFieldValidatorBox::validate_assignment(
None,
"Node",
"next",
);
assert!(result.is_err(), "Untracked value should be forbidden");
assert!(result.unwrap_err().contains("untracked value"));
}
#[test]
fn test_validate_primitive_forbidden() {
let result = WeakFieldValidatorBox::validate_assignment(
Some(&MirType::Integer),
"Node",
"count",
);
assert!(result.is_err(), "Primitive should be forbidden");
assert!(result.unwrap_err().contains("Weak fields require WeakRef"));
}
}