feat(joinir): Phase 224-cont - Promoted variable tracking for lowerer
- Add promoted_loopbodylocals field to CarrierInfo - Record promoted variables in Pattern2 promotion handler - Filter promoted variables in lowerer LoopBodyLocal check - digit_pos → is_digit_pos promotion now continues to lowering Closes Phase 224 lowerer integration gap. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -46,6 +46,12 @@ pub struct CarrierInfo {
|
||||
pub carriers: Vec<CarrierVar>,
|
||||
/// Phase 171-C-5: Trim pattern helper (if this CarrierInfo was created from Trim promotion)
|
||||
pub trim_helper: Option<crate::mir::loop_pattern_detection::trim_loop_helper::TrimLoopHelper>,
|
||||
/// Phase 224: Promoted LoopBodyLocal variables (e.g., "digit_pos" promoted to "is_digit_pos")
|
||||
///
|
||||
/// These variables were originally LoopBodyLocal but have been promoted to carriers
|
||||
/// during condition promotion (e.g., DigitPosPromoter). The lowerer should skip
|
||||
/// LoopBodyLocal checks for these variables.
|
||||
pub promoted_loopbodylocals: Vec<String>,
|
||||
}
|
||||
|
||||
impl CarrierInfo {
|
||||
@ -106,6 +112,7 @@ impl CarrierInfo {
|
||||
loop_var_id,
|
||||
carriers,
|
||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||
})
|
||||
}
|
||||
|
||||
@ -163,6 +170,7 @@ impl CarrierInfo {
|
||||
loop_var_id,
|
||||
carriers,
|
||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||
})
|
||||
}
|
||||
|
||||
@ -189,6 +197,7 @@ impl CarrierInfo {
|
||||
loop_var_id,
|
||||
carriers,
|
||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,6 +251,13 @@ impl CarrierInfo {
|
||||
if other.trim_helper.is_some() {
|
||||
self.trim_helper = other.trim_helper.clone();
|
||||
}
|
||||
|
||||
// Phase 224: Merge promoted_loopbodylocals (deduplicate)
|
||||
for promoted_var in &other.promoted_loopbodylocals {
|
||||
if !self.promoted_loopbodylocals.contains(promoted_var) {
|
||||
self.promoted_loopbodylocals.push(promoted_var.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase 171-C-5: Get Trim pattern helper
|
||||
|
||||
@ -154,8 +154,29 @@ pub(crate) fn lower_loop_with_break_minimal(
|
||||
);
|
||||
|
||||
if loop_cond_scope.has_loop_body_local() {
|
||||
// Phase 224: Filter out promoted variables from body-local check
|
||||
// Variables that were promoted to carriers should not trigger the error
|
||||
let body_local_names = extract_body_local_names(&loop_cond_scope.vars);
|
||||
return Err(format_unsupported_condition_error("pattern2", &body_local_names));
|
||||
let unpromoted_locals: Vec<&String> = body_local_names
|
||||
.iter()
|
||||
.filter(|name| !carrier_info.promoted_loopbodylocals.contains(*name))
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
if !unpromoted_locals.is_empty() {
|
||||
eprintln!(
|
||||
"[joinir/pattern2] Phase 224: {} body-local variables after promotion filter: {:?}",
|
||||
unpromoted_locals.len(),
|
||||
unpromoted_locals
|
||||
);
|
||||
return Err(format_unsupported_condition_error("pattern2", &unpromoted_locals));
|
||||
}
|
||||
|
||||
eprintln!(
|
||||
"[joinir/pattern2] Phase 224: All {} body-local variables were promoted: {:?}",
|
||||
body_local_names.len(),
|
||||
body_local_names
|
||||
);
|
||||
}
|
||||
|
||||
eprintln!(
|
||||
|
||||
Reference in New Issue
Block a user