feat(joinir): Phase 223.5 - LoopBodyCondPromoter Pattern2 integration
- Integrate LoopBodyCondPromoter into Pattern2 (break condition analysis) - Add Pattern2 error message functions to error_messages.rs - Create A-4 minimal test (phase2235_p2_digit_pos_min.hako) - Unified promotion structure for Pattern2/Pattern4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -95,3 +95,210 @@ mod tests {
|
||||
assert!(err.contains("Pattern 4 supports"));
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Pattern 4 Specific Error Messages
|
||||
// ========================================================================
|
||||
|
||||
/// Pattern4: Cannot promote LoopBodyLocal variables in condition
|
||||
///
|
||||
/// Used when LoopBodyCondPromoter fails to promote a LoopBodyLocal variable
|
||||
/// used in loop conditions to a bool carrier.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `vars` - Names of LoopBodyLocal variables that failed promotion
|
||||
/// * `reason` - Human-readable reason for the failure
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let err = format_error_pattern4_promotion_failed(&["ch"], "not a Trim pattern");
|
||||
/// // Returns: "[cf_loop/pattern4] Cannot promote LoopBodyLocal variables ["ch"]: not a Trim pattern"
|
||||
/// ```
|
||||
pub fn format_error_pattern4_promotion_failed(vars: &[String], reason: &str) -> String {
|
||||
format!(
|
||||
"[cf_loop/pattern4] Cannot promote LoopBodyLocal variables {:?}: {}",
|
||||
vars, reason
|
||||
)
|
||||
}
|
||||
|
||||
/// Pattern4: Trim pattern detected but not safe
|
||||
///
|
||||
/// Used when a Trim pattern is detected but does not meet safety criteria
|
||||
/// (e.g., too many whitespace characters, unsafe structure).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `carrier_name` - Name of the carrier variable
|
||||
/// * `whitespace_count` - Number of whitespace characters detected
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let err = format_error_pattern4_trim_not_safe("is_whitespace", 5);
|
||||
/// // Returns: "[cf_loop/pattern4] Trim pattern detected but not safe: carrier='is_whitespace', whitespace_count=5"
|
||||
/// ```
|
||||
pub fn format_error_pattern4_trim_not_safe(carrier_name: &str, whitespace_count: usize) -> String {
|
||||
format!(
|
||||
"[cf_loop/pattern4] Trim pattern detected but not safe: carrier='{}', whitespace_count={}",
|
||||
carrier_name, whitespace_count
|
||||
)
|
||||
}
|
||||
|
||||
/// Pattern4: Lowering failed
|
||||
///
|
||||
/// Generic error wrapper for Pattern 4 lowering failures.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `cause` - The underlying error message
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let err = format_error_pattern4_lowering_failed("JoinIR conversion error");
|
||||
/// // Returns: "[cf_loop/pattern4] Lowering failed: JoinIR conversion error"
|
||||
/// ```
|
||||
pub fn format_error_pattern4_lowering_failed(cause: &str) -> String {
|
||||
format!("[cf_loop/pattern4] Lowering failed: {}", cause)
|
||||
}
|
||||
|
||||
/// Pattern4: Carrier not found in variable_map
|
||||
///
|
||||
/// Used when an expected carrier variable is missing from variable_map,
|
||||
/// indicating an exit binding is not properly generated.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `carrier_name` - Name of the missing carrier variable
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let err = format_error_pattern4_carrier_not_found("sum");
|
||||
/// // Returns: "[cf_loop/pattern4] Carrier 'sum' not found in variable_map - exit binding missing"
|
||||
/// ```
|
||||
pub fn format_error_pattern4_carrier_not_found(carrier_name: &str) -> String {
|
||||
format!(
|
||||
"[cf_loop/pattern4] Carrier '{}' not found in variable_map - exit binding missing",
|
||||
carrier_name
|
||||
)
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Pattern 2 Specific Error Messages
|
||||
// ========================================================================
|
||||
|
||||
/// Pattern2: Cannot promote LoopBodyLocal variables in condition
|
||||
///
|
||||
/// Used when LoopBodyCondPromoter fails to promote a LoopBodyLocal variable
|
||||
/// used in loop/break conditions to a bool carrier.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `vars` - Names of LoopBodyLocal variables that failed promotion
|
||||
/// * `reason` - Human-readable reason for the failure
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let err = format_error_pattern2_promotion_failed(&["ch"], "not a Trim pattern");
|
||||
/// // Returns: "[cf_loop/pattern2] Cannot promote LoopBodyLocal variables ["ch"]: not a Trim pattern"
|
||||
/// ```
|
||||
pub fn format_error_pattern2_promotion_failed(vars: &[String], reason: &str) -> String {
|
||||
format!(
|
||||
"[cf_loop/pattern2] Cannot promote LoopBodyLocal variables {:?}: {}",
|
||||
vars, reason
|
||||
)
|
||||
}
|
||||
|
||||
/// Pattern2: Trim pattern detected but not safe
|
||||
///
|
||||
/// Used when a Trim pattern is detected but does not meet safety criteria.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `carrier_name` - Name of the carrier variable
|
||||
/// * `whitespace_count` - Number of whitespace characters detected
|
||||
pub fn format_error_pattern2_trim_not_safe(carrier_name: &str, whitespace_count: usize) -> String {
|
||||
format!(
|
||||
"[cf_loop/pattern2] Trim pattern detected but not safe: carrier='{}', whitespace_count={}",
|
||||
carrier_name, whitespace_count
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod pattern2_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_format_error_pattern2_promotion_failed() {
|
||||
let vars = vec!["ch".to_string(), "digit_pos".to_string()];
|
||||
let err = format_error_pattern2_promotion_failed(&vars, "cascading LoopBodyLocal");
|
||||
|
||||
assert!(err.contains("[cf_loop/pattern2]"));
|
||||
assert!(err.contains("Cannot promote"));
|
||||
assert!(err.contains("ch"));
|
||||
assert!(err.contains("digit_pos"));
|
||||
assert!(err.contains("cascading LoopBodyLocal"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_error_pattern2_trim_not_safe() {
|
||||
let err = format_error_pattern2_trim_not_safe("is_digit", 3);
|
||||
|
||||
assert!(err.contains("[cf_loop/pattern2]"));
|
||||
assert!(err.contains("Trim pattern"));
|
||||
assert!(err.contains("not safe"));
|
||||
assert!(err.contains("is_digit"));
|
||||
assert!(err.contains("whitespace_count=3"));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod pattern4_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_format_error_pattern4_promotion_failed() {
|
||||
let vars = vec!["ch".to_string(), "temp".to_string()];
|
||||
let err = format_error_pattern4_promotion_failed(&vars, "not a Trim pattern");
|
||||
|
||||
assert!(err.contains("[cf_loop/pattern4]"));
|
||||
assert!(err.contains("Cannot promote"));
|
||||
assert!(err.contains("ch"));
|
||||
assert!(err.contains("temp"));
|
||||
assert!(err.contains("not a Trim pattern"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_error_pattern4_trim_not_safe() {
|
||||
let err = format_error_pattern4_trim_not_safe("is_whitespace", 5);
|
||||
|
||||
assert!(err.contains("[cf_loop/pattern4]"));
|
||||
assert!(err.contains("Trim pattern"));
|
||||
assert!(err.contains("not safe"));
|
||||
assert!(err.contains("is_whitespace"));
|
||||
assert!(err.contains("whitespace_count=5"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_error_pattern4_lowering_failed() {
|
||||
let err = format_error_pattern4_lowering_failed("JoinIR error");
|
||||
|
||||
assert!(err.contains("[cf_loop/pattern4]"));
|
||||
assert!(err.contains("Lowering failed"));
|
||||
assert!(err.contains("JoinIR error"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_error_pattern4_carrier_not_found() {
|
||||
let err = format_error_pattern4_carrier_not_found("sum");
|
||||
|
||||
assert!(err.contains("[cf_loop/pattern4]"));
|
||||
assert!(err.contains("Carrier 'sum'"));
|
||||
assert!(err.contains("not found"));
|
||||
assert!(err.contains("exit binding missing"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user