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:
@ -308,6 +308,9 @@ impl MirBuilder {
|
||||
promoted_var, carrier_name
|
||||
);
|
||||
|
||||
// Phase 224: Record promoted variable before merging
|
||||
carrier_info.promoted_loopbodylocals.push(promoted_var.clone());
|
||||
|
||||
// Merge promoted carrier into existing CarrierInfo
|
||||
carrier_info.merge_from(&promoted_carrier);
|
||||
|
||||
@ -316,6 +319,10 @@ impl MirBuilder {
|
||||
carrier_name,
|
||||
carrier_info.carrier_count()
|
||||
);
|
||||
eprintln!(
|
||||
"[pattern2/cond_promoter] Phase 224: Recorded promoted variable '{}' in carrier_info.promoted_loopbodylocals",
|
||||
promoted_var
|
||||
);
|
||||
|
||||
// Check if this is a safe Trim pattern
|
||||
if let Some(helper) = carrier_info.trim_helper() {
|
||||
|
||||
@ -72,6 +72,7 @@ impl Pattern4CarrierAnalyzer {
|
||||
loop_var_id: all_carriers.loop_var_id,
|
||||
carriers: updated_carriers,
|
||||
trim_helper: all_carriers.trim_helper.clone(),
|
||||
promoted_loopbodylocals: all_carriers.promoted_loopbodylocals.clone(), // Phase 224
|
||||
})
|
||||
}
|
||||
|
||||
@ -287,6 +288,7 @@ mod tests {
|
||||
},
|
||||
],
|
||||
trim_helper: None,
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224
|
||||
};
|
||||
|
||||
// Analyze carriers
|
||||
|
||||
@ -404,6 +404,7 @@ mod tests {
|
||||
},
|
||||
],
|
||||
trim_helper: None,
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224
|
||||
},
|
||||
loop_scope: LoopScopeShapeBuilder::empty_body_locals(
|
||||
BasicBlockId(0),
|
||||
@ -442,6 +443,7 @@ mod tests {
|
||||
carrier_name: "is_whitespace".to_string(),
|
||||
whitespace_chars: vec![" ".to_string(), "\t".to_string()],
|
||||
}),
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224
|
||||
},
|
||||
loop_scope: LoopScopeShapeBuilder::empty_body_locals(
|
||||
BasicBlockId(0),
|
||||
|
||||
@ -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