diff --git a/src/mir/builder.rs b/src/mir/builder.rs index 6e630dd7..ca7fba24 100644 --- a/src/mir/builder.rs +++ b/src/mir/builder.rs @@ -456,6 +456,17 @@ impl MirBuilder { /// Build variable access pub(super) fn build_variable_access(&mut self, name: String) -> Result { + // Step 5-5-G: __pin$ variables should NEVER be accessed from variable_map + // They are transient temporaries created during expression building and + // should not persist across blocks. If we see one here, it's a compiler bug. + if name.starts_with("__pin$") { + return Err(format!( + "COMPILER BUG: Attempt to access __pin$ temporary '{}' from variable_map. \ + __pin$ variables should only exist as direct SSA values, not as named variables.", + name + )); + } + if let Some(&value_id) = self.variable_map.get(&name) { Ok(value_id) } else { @@ -500,8 +511,18 @@ impl MirBuilder { // SSA + PHI merges work correctly without explicit pinning here. // The expression building already creates necessary temporaries. - // In SSA form, each assignment creates a new value - self.variable_map.insert(var_name.clone(), value_id); + // Step 5-5-F: NEVER insert __pin$ temporaries into variable_map + // __pin$ variables are transient compiler-generated temporaries that should + // never be tracked as real variables. They are used only within expression + // building and should not persist across blocks or loops. + // + // BUG FIX: Previously, __pin$ variables would be inserted into variable_map, + // causing stale references after LoopForm transformation renumbers blocks. + // Result: VM would try to read undefined ValueIds (e.g., ValueId(270) at bb303). + if !var_name.starts_with("__pin$") { + // In SSA form, each assignment creates a new value + self.variable_map.insert(var_name.clone(), value_id); + } Ok(value_id) }