Files
hakorune/src/mir/value_id.rs
nyash-codex 7aa1b71d94 test(mir): fix test compilation after Call instruction callee field addition
Fixes test compilation errors caused by adding callee: Option<Callee> field
to MirInstruction::Call in previous commits.

Changes:
- tests/mir_instruction_unit.rs:
  - Add callee: None to all Call instruction constructions
  - Ensures backward compatibility with existing tests

- src/mir/instruction/tests.rs:
  - Add callee: None to Call instruction in phi_merge_if test
  - Maintains test correctness after Call signature change

- src/mir/value_id.rs:
  - Add ValueId::INVALID constant (u32::MAX)
  - Provides clear sentinel value for invalid/placeholder IDs

- src/mir/phi_core/loopform_builder.rs:
  - Replace deprecated ValueId::from() with ValueId::new()
  - Replace deprecated BasicBlockId::from() with BasicBlockId::new()
  - Ensures consistency with updated ID construction patterns

Test Status:
- Original errors from our commit: 6 → 0 
- Remaining errors: 45 (pre-existing, unrelated to our changes)
  - 14: Missing interpreter module (legacy)
  - 11: Missing VM in backend::vm (moved)
  - 7: Missing jit module (archived)
  - 5: Missing MirInterpreter methods (legacy)
  - 4: Missing Box operator methods (pre-existing)

All test errors related to LocalSSA and Call instruction changes are resolved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 09:45:03 +09:00

201 lines
4.2 KiB
Rust

/*!
* MIR Value ID System - SSA value tracking
*
* Implements unique identifiers for SSA values with type safety
*/
use std::fmt;
/// Unique identifier for SSA values within a function
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ValueId(pub u32);
impl ValueId {
/// Invalid/uninitialized ValueId sentinel
pub const INVALID: Self = ValueId(u32::MAX);
/// Create a new ValueId
pub fn new(id: u32) -> Self {
ValueId(id)
}
/// Get the raw ID value
pub fn as_u32(self) -> u32 {
self.0
}
/// Create ValueId from usize (for array indexing)
pub fn from_usize(id: usize) -> Self {
ValueId(id as u32)
}
/// Convert to usize (for array indexing)
pub fn to_usize(self) -> usize {
self.0 as usize
}
}
impl fmt::Display for ValueId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "%{}", self.0)
}
}
/// Local variable identifier (before SSA conversion)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LocalId(pub u32);
impl LocalId {
/// Create a new LocalId
pub fn new(id: u32) -> Self {
LocalId(id)
}
/// Get the raw ID value
pub fn as_u32(self) -> u32 {
self.0
}
}
impl fmt::Display for LocalId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "local_{}", self.0)
}
}
/// Value ID generator for unique SSA value creation
#[derive(Debug, Clone)]
pub struct ValueIdGenerator {
next_id: u32,
}
impl ValueIdGenerator {
/// Create a new generator starting from 0
pub fn new() -> Self {
Self { next_id: 0 }
}
/// Generate the next unique ValueId
pub fn next(&mut self) -> ValueId {
let id = ValueId(self.next_id);
self.next_id += 1;
id
}
/// Peek at the next ID without consuming it
pub fn peek_next(&self) -> ValueId {
ValueId(self.next_id)
}
/// Reset the generator (for testing)
pub fn reset(&mut self) {
self.next_id = 0;
}
}
impl Default for ValueIdGenerator {
fn default() -> Self {
Self::new()
}
}
/// Local ID generator for variable naming
#[derive(Debug, Clone)]
pub struct LocalIdGenerator {
next_id: u32,
}
impl LocalIdGenerator {
/// Create a new generator starting from 0
pub fn new() -> Self {
Self { next_id: 0 }
}
/// Generate the next unique LocalId
pub fn next(&mut self) -> LocalId {
let id = LocalId(self.next_id);
self.next_id += 1;
id
}
/// Reset the generator (for testing)
pub fn reset(&mut self) {
self.next_id = 0;
}
}
impl Default for LocalIdGenerator {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_value_id_creation() {
let id1 = ValueId::new(0);
let id2 = ValueId::new(1);
assert_eq!(id1.as_u32(), 0);
assert_eq!(id2.as_u32(), 1);
assert_ne!(id1, id2);
assert_eq!(format!("{}", id1), "%0");
assert_eq!(format!("{}", id2), "%1");
}
#[test]
fn test_value_id_generator() {
let mut gen = ValueIdGenerator::new();
let id1 = gen.next();
let id2 = gen.next();
let id3 = gen.next();
assert_eq!(id1, ValueId(0));
assert_eq!(id2, ValueId(1));
assert_eq!(id3, ValueId(2));
assert_eq!(gen.peek_next(), ValueId(3));
}
#[test]
fn test_local_id_creation() {
let local1 = LocalId::new(0);
let local2 = LocalId::new(1);
assert_eq!(format!("{}", local1), "local_0");
assert_eq!(format!("{}", local2), "local_1");
}
#[test]
fn test_local_id_generator() {
let mut gen = LocalIdGenerator::new();
let local1 = gen.next();
let local2 = gen.next();
assert_eq!(local1, LocalId(0));
assert_eq!(local2, LocalId(1));
}
#[test]
fn test_value_id_ordering() {
let id1 = ValueId(1);
let id2 = ValueId(2);
let id3 = ValueId(3);
assert!(id1 < id2);
assert!(id2 < id3);
assert!(id1 < id3);
let mut ids = vec![id3, id1, id2];
ids.sort();
assert_eq!(ids, vec![id1, id2, id3]);
}
}