Phase 2-4 で移行漏れがあったファイルを修正。
## Changes
- Fixed all remaining compilation errors from incomplete Phase 2-4 migration
- Updated access sites to use scope_ctx.* for 7 legacy fields:
1. current_function → scope_ctx.current_function
2. lexical_scope_stack → scope_ctx.lexical_scope_stack
3. if_merge_stack → scope_ctx.if_merge_stack
4. debug_scope_stack → scope_ctx.debug_scope_stack
- Updated visibility of ScopeContext to pub(in crate::mir) for cross-module access
- Removed dual-write legacy code in lexical_scope.rs, builder.rs
- Updated documentation comments in phi_helpers.rs
## Files Modified (20 files)
Core access migration:
- src/mir/builder/method_call_handlers.rs
- src/mir/builder/control_flow/joinir/routing.rs
- src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs
- src/mir/builder/if_form.rs
- src/mir/builder/ops.rs (4 occurrences)
- src/mir/builder/observe/resolve.rs (2 occurrences)
- src/mir/builder/observe/ssa.rs
- src/mir/builder/receiver.rs
- src/mir/loop_api.rs (3 occurrences)
- src/mir/region/observer.rs (3 occurrences)
- src/mir/utils/control_flow.rs
- src/mir/utils/phi_helpers.rs (4 occurrences + docs)
Dual-write removal:
- src/mir/builder/vars/lexical_scope.rs (push/pop/declare)
- src/mir/builder.rs (if_merge, debug_scope, emit_instruction)
Visibility updates:
- src/mir/builder/scope_context.rs (struct + fields)
## Tests
- cargo build --release: SUCCESS (0 errors, 191 warnings)
- Phase 2-4 migration now fully complete
- Note: Test failures exist but are unrelated (Phase 2-5 binding_map issue)
Phase 2-4 now fully complete ✅
150 lines
5.0 KiB
Rust
150 lines
5.0 KiB
Rust
/*!
|
|
* Loop Builder Facade (Minimal API)
|
|
*
|
|
* Goal: Decouple loop construction from concrete MirBuilder types by exposing
|
|
* a small trait that both legacy (mir::builder::MirBuilder) and modularized
|
|
* builders can implement. This enables shared helpers and gradual migration.
|
|
*
|
|
* Note: Only legacy MirBuilder is wired for now to keep WIP modularized code
|
|
* out of the main build. The modularized builder can implement this trait
|
|
* later without changing callers.
|
|
*/
|
|
|
|
use super::{BasicBlockId, MirInstruction, ValueId};
|
|
|
|
/// Minimal API for constructing loops and emitting instructions
|
|
pub trait LoopBuilderApi {
|
|
/// Allocate a new basic block id
|
|
fn new_block(&mut self) -> BasicBlockId;
|
|
/// Get current block id
|
|
fn current_block(&self) -> Result<BasicBlockId, String>;
|
|
/// Switch current block, creating it if needed
|
|
fn start_new_block(&mut self, block: BasicBlockId) -> Result<(), String>;
|
|
/// Emit an instruction to the current block
|
|
fn emit(&mut self, inst: MirInstruction) -> Result<(), String>;
|
|
/// Allocate a new SSA value id
|
|
fn new_value(&mut self) -> ValueId;
|
|
|
|
/// Add predecessor edge to a block (CFG maintenance)
|
|
fn add_predecessor(&mut self, _block: BasicBlockId, _pred: BasicBlockId) -> Result<(), String> {
|
|
Err("add_predecessor not implemented".into())
|
|
}
|
|
/// Seal a block when all predecessors are known
|
|
fn seal_block(&mut self, _block: BasicBlockId) -> Result<(), String> {
|
|
Err("seal_block not implemented".into())
|
|
}
|
|
/// Insert a phi at block start
|
|
fn insert_phi_at_block_start(
|
|
&mut self,
|
|
_block: BasicBlockId,
|
|
_dst: ValueId,
|
|
_inputs: Vec<(BasicBlockId, ValueId)>,
|
|
) -> Result<(), String> {
|
|
Err("insert_phi_at_block_start not implemented".into())
|
|
}
|
|
}
|
|
|
|
/// Helper: simplified loop lowering usable by any LoopBuilderApi implementor
|
|
pub fn build_simple_loop<L: LoopBuilderApi>(
|
|
lb: &mut L,
|
|
condition: ValueId,
|
|
build_body: &mut dyn FnMut(&mut L) -> Result<(), String>,
|
|
) -> Result<ValueId, String> {
|
|
let header = lb.new_block();
|
|
let body = lb.new_block();
|
|
let after = lb.new_block();
|
|
|
|
// Jump to header
|
|
lb.emit(MirInstruction::Jump { target: header })?;
|
|
|
|
// Header: branch on provided condition
|
|
lb.start_new_block(header)?;
|
|
lb.emit(MirInstruction::Branch {
|
|
condition,
|
|
then_bb: body,
|
|
else_bb: after,
|
|
})?;
|
|
|
|
// Body
|
|
lb.start_new_block(body)?;
|
|
build_body(lb)?;
|
|
lb.emit(MirInstruction::Jump { target: header })?;
|
|
|
|
// After: return void value
|
|
lb.start_new_block(after)?;
|
|
let void_id = lb.new_value();
|
|
lb.emit(MirInstruction::Const {
|
|
dst: void_id,
|
|
value: crate::mir::ConstValue::Void,
|
|
})?;
|
|
Ok(void_id)
|
|
}
|
|
|
|
// === Legacy wiring: implement LoopBuilderApi for mir::builder::MirBuilder ===
|
|
impl LoopBuilderApi for super::builder::MirBuilder {
|
|
fn new_block(&mut self) -> BasicBlockId {
|
|
self.core_ctx.next_block()
|
|
}
|
|
fn current_block(&self) -> Result<BasicBlockId, String> {
|
|
self.current_block
|
|
.ok_or_else(|| "No current block".to_string())
|
|
}
|
|
fn start_new_block(&mut self, block: BasicBlockId) -> Result<(), String> {
|
|
super::builder::MirBuilder::start_new_block(self, block)
|
|
}
|
|
fn emit(&mut self, inst: MirInstruction) -> Result<(), String> {
|
|
super::builder::MirBuilder::emit_instruction(self, inst)
|
|
}
|
|
fn new_value(&mut self) -> ValueId {
|
|
// Use function-local allocator to avoid colliding with existing
|
|
// ValueIds in the current function.
|
|
self.next_value_id()
|
|
}
|
|
|
|
fn add_predecessor(&mut self, block: BasicBlockId, pred: BasicBlockId) -> Result<(), String> {
|
|
if let Some(ref mut f) = self.scope_ctx.current_function {
|
|
if let Some(bb) = f.get_block_mut(block) {
|
|
bb.add_predecessor(pred);
|
|
Ok(())
|
|
} else {
|
|
Err(format!("Block {} not found", block.as_u32()))
|
|
}
|
|
} else {
|
|
Err("No current function".into())
|
|
}
|
|
}
|
|
|
|
fn seal_block(&mut self, block: BasicBlockId) -> Result<(), String> {
|
|
if let Some(ref mut f) = self.scope_ctx.current_function {
|
|
if let Some(bb) = f.get_block_mut(block) {
|
|
bb.seal();
|
|
Ok(())
|
|
} else {
|
|
Err(format!("Block {} not found", block.as_u32()))
|
|
}
|
|
} else {
|
|
Err("No current function".into())
|
|
}
|
|
}
|
|
|
|
fn insert_phi_at_block_start(
|
|
&mut self,
|
|
block: BasicBlockId,
|
|
dst: ValueId,
|
|
inputs: Vec<(BasicBlockId, ValueId)>,
|
|
) -> Result<(), String> {
|
|
if let Some(ref mut f) = self.scope_ctx.current_function {
|
|
crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
|
|
f,
|
|
block,
|
|
dst,
|
|
inputs,
|
|
self.metadata_ctx.current_span(),
|
|
);
|
|
Ok(())
|
|
} else {
|
|
Err("No current function".into())
|
|
}
|
|
}
|
|
}
|