feat(joinir): Phase 224-D - ConditionAlias for promoted variable resolution
- Add ConditionAlias type to CarrierInfo (old_name → carrier_name) - Record aliases in DigitPosPromoter and TrimPatternInfo - Resolve aliases in Pattern2 ConditionEnv building - digit_pos now correctly resolves to is_digit_pos carrier Fixes "Variable 'digit_pos' not bound in ConditionEnv" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -18,6 +18,29 @@
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap; // Phase 222.5-D: HashMap → BTreeMap for determinism
|
||||
|
||||
/// Phase 224-D: Alias for promoted LoopBodyLocal in condition expressions
|
||||
///
|
||||
/// When a LoopBodyLocal variable is promoted to a carrier, the original variable
|
||||
/// name must still be resolvable in condition expressions for backward compatibility.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// // Original variable: "digit_pos"
|
||||
/// // Promoted carrier: "is_digit_pos"
|
||||
/// ConditionAlias {
|
||||
/// old_name: "digit_pos".to_string(),
|
||||
/// carrier_name: "is_digit_pos".to_string(),
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ConditionAlias {
|
||||
/// Original variable name (e.g., "digit_pos")
|
||||
pub old_name: String,
|
||||
/// Promoted carrier name (e.g., "is_digit_pos")
|
||||
pub carrier_name: String,
|
||||
}
|
||||
|
||||
/// Information about a single carrier variable
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CarrierVar {
|
||||
@ -52,6 +75,12 @@ pub struct CarrierInfo {
|
||||
/// during condition promotion (e.g., DigitPosPromoter). The lowerer should skip
|
||||
/// LoopBodyLocal checks for these variables.
|
||||
pub promoted_loopbodylocals: Vec<String>,
|
||||
/// Phase 224-D: Condition aliases for promoted LoopBodyLocal variables
|
||||
///
|
||||
/// Maps old variable names to their promoted carrier names for condition resolution.
|
||||
/// This allows break/continue conditions to reference promoted variables by their
|
||||
/// original names (e.g., `if digit_pos < 0` still works after promotion to "is_digit_pos").
|
||||
pub condition_aliases: Vec<ConditionAlias>,
|
||||
}
|
||||
|
||||
impl CarrierInfo {
|
||||
@ -113,6 +142,7 @@ impl CarrierInfo {
|
||||
carriers,
|
||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||
condition_aliases: Vec::new(), // Phase 224-D: No aliases by default
|
||||
})
|
||||
}
|
||||
|
||||
@ -171,6 +201,7 @@ impl CarrierInfo {
|
||||
carriers,
|
||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||
condition_aliases: Vec::new(), // Phase 224-D: No aliases by default
|
||||
})
|
||||
}
|
||||
|
||||
@ -198,6 +229,7 @@ impl CarrierInfo {
|
||||
carriers,
|
||||
trim_helper: None, // Phase 171-C-5: No Trim pattern by default
|
||||
promoted_loopbodylocals: Vec::new(), // Phase 224: No promoted variables by default
|
||||
condition_aliases: Vec::new(), // Phase 224-D: No aliases by default
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,6 +290,13 @@ impl CarrierInfo {
|
||||
self.promoted_loopbodylocals.push(promoted_var.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 224-D: Merge condition_aliases (deduplicate by old_name)
|
||||
for alias in &other.condition_aliases {
|
||||
if !self.condition_aliases.iter().any(|a| a.old_name == alias.old_name) {
|
||||
self.condition_aliases.push(alias.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase 171-C-5: Get Trim pattern helper
|
||||
|
||||
Reference in New Issue
Block a user