refactor(mir): phase261 p0 enforce edge-args writer ssot (verify + sync)

This commit is contained in:
2025-12-21 08:32:04 +09:00
parent 89c5fc2654
commit 7c9f453fc6
4 changed files with 65 additions and 25 deletions

View File

@ -16,6 +16,25 @@
- P2: `BasicBlock.jump_args` を削除terminator operand を SSOT 化)
- P3: spans を `Vec<Spanned<_>>` に収束(段階導入)
## Phase 261 P0 チェックリストlegacy-only 経路の棚卸し)
- `src/mir/basic_block.rs:119` — reason: legacy layout の初期値が None空メタ; expected: OKlegacy 未設定時の既定)
- `src/mir/basic_block.rs:239` — reason: out_edges が legacy fallback を持つ; expected: Jump/Branch で edge-args を書く経路を増やし、verify で legacy-only を検出
- `src/mir/basic_block.rs:254` — reason: legacy setter API; expected: writer 側は edge-args を併記する経路に統一
- `src/mir/basic_block.rs:281` — reason: legacy edge-args 生成 API; expected: read-side の移行完了後に削除P2
- `src/mir/basic_block.rs:337` — reason: legacy edge-args fallback; expected: verify で legacy-only を検出し、P2で撤去
- `src/mir/join_ir_vm_bridge/handlers/call.rs:193` — reason: tail-call Return の legacy 付与exit wiring; expected: edge-args SSOT 化のための設計判断が必要Return には edge-args を持てない)
- `src/mir/join_ir_vm_bridge/handlers/jump.rs:213` — reason: cond jump の exit block Return に legacy 付与; expected: 同上Return 経由のため)
- `src/mir/join_ir_vm_bridge/handlers/jump.rs:249` — reason: tail-call Return の legacy 付与; expected: 同上
- `src/mir/join_ir_vm_bridge/joinir_block_converter.rs:438` — reason: tail-call Return の legacy 付与; expected: 同上
- `src/mir/join_ir_vm_bridge/joinir_block_converter.rs:508` — reason: cond jump の exit block Return に legacy 付与; expected: 同上
- `src/mir/join_ir_vm_bridge/joinir_block_converter.rs:551` — reason: tail-call Return の legacy 付与; expected: 同上
- `src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs:425` — reason: exit Return の legacy 付与; expected: 同上
- `src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs:471` — reason: finalize_block の legacy 付与; expected: 同上
- `src/mir/builder/control_flow/joinir/merge/rewriter/exit_collection.rs:64` — reason: legacy edge-args を read; expected: edge-args SSOT 経路に寄せて置換P1〜P2
- `src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs:415` — reason: legacy edge-args read; expected: 同上
- `src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs:930` — reason: legacy edge-args read; expected: 同上
## Current First FAIL (SSOT)
- **After Phase 260 P0.3**: `core_direct_array_oob_set_rc_vm / Stage-B compile / JoinIR Pattern2 LoopBodyLocal(seg)`

View File

@ -252,8 +252,14 @@ impl BasicBlock {
/// Set legacy jump args metadata (migration helper)
pub fn set_legacy_jump_args(&mut self, values: Vec<ValueId>, layout: Option<JumpArgsLayout>) {
self.jump_args = Some(values);
self.jump_args = Some(values.clone());
self.jump_args_layout = layout;
if let (Some(layout), Some(MirInstruction::Jump { target, edge_args: None })) =
(layout, self.terminator.clone())
{
let edge_args = EdgeArgs { layout, values };
self.set_jump_with_edge_args(target, Some(edge_args));
}
}
/// Clear legacy jump args metadata (migration helper)

View File

@ -70,18 +70,19 @@ pub fn check_control_flow(function: &MirFunction) -> Result<(), Vec<Verification
}
}
}
MirInstruction::Branch {
then_edge_args,
else_edge_args,
..
} => {
if block.has_legacy_jump_args()
&& (then_edge_args.is_some() || else_edge_args.is_some())
{
MirInstruction::Jump { edge_args: None, .. } => {
if block.has_legacy_jump_args() {
errors.push(VerificationError::ControlFlowError {
block: *block_id,
reason: "Legacy jump_args present on multi-edge terminator with edge-args"
.to_string(),
reason: "Legacy jump_args present but Jump edge-args missing".to_string(),
});
}
}
MirInstruction::Branch { .. } => {
if block.has_legacy_jump_args() {
errors.push(VerificationError::ControlFlowError {
block: *block_id,
reason: "Legacy jump_args present on Branch terminator".to_string(),
});
}
}

View File

@ -83,25 +83,37 @@ impl RuntimeProfile {
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Mutex;
static ENV_LOCK: Mutex<()> = Mutex::new(());
fn with_env_lock<F: FnOnce()>(f: F) {
let _guard = ENV_LOCK.lock().expect("env lock poisoned");
f();
}
#[test]
fn test_runtime_profile_from_env_default() {
// Without setting env, should return Default
std::env::remove_var("NYASH_RUNTIME_PROFILE");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default);
with_env_lock(|| {
// Without setting env, should return Default
std::env::remove_var("NYASH_RUNTIME_PROFILE");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default);
});
}
#[test]
fn test_runtime_profile_from_env_nofs() {
// Test "no-fs" variant
std::env::set_var("NYASH_RUNTIME_PROFILE", "no-fs");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs);
with_env_lock(|| {
// Test "no-fs" variant
std::env::set_var("NYASH_RUNTIME_PROFILE", "no-fs");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs);
// Test "nofs" variant
std::env::set_var("NYASH_RUNTIME_PROFILE", "nofs");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs);
// Test "nofs" variant
std::env::set_var("NYASH_RUNTIME_PROFILE", "nofs");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs);
std::env::remove_var("NYASH_RUNTIME_PROFILE");
std::env::remove_var("NYASH_RUNTIME_PROFILE");
});
}
#[test]
@ -112,9 +124,11 @@ mod tests {
#[test]
fn test_runtime_profile_from_env_unknown_defaults_to_default() {
// Unknown profile env var → Default に fallback
std::env::set_var("NYASH_RUNTIME_PROFILE", "unknown-profile");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default);
std::env::remove_var("NYASH_RUNTIME_PROFILE");
with_env_lock(|| {
// Unknown profile env var → Default に fallback
std::env::set_var("NYASH_RUNTIME_PROFILE", "unknown-profile");
assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default);
std::env::remove_var("NYASH_RUNTIME_PROFILE");
});
}
}