refactor(joinir): add hints for Phase107/104/100 policy rejects
- balanced_depth_scan: missing_tail_inc, missing_return_i hints - read_digits: missing_eos_guard, digit_set_mismatch hints - pinned: missing_host_id hint - Gradual migration (representative cases only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -193,9 +193,11 @@ impl Pattern2InputsFactsBox {
|
||||
}
|
||||
captured_env.insert_pinned(pinned_name, host_id);
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Pinned local '{}' not found in variable_map (internal error)",
|
||||
pinned_name
|
||||
use crate::mir::join_ir::lowering::error_tags;
|
||||
return Err(error_tags::freeze_with_hint(
|
||||
"phase100/pinned/missing_host_id",
|
||||
&format!("Pinned local '{}' not found in variable_map", pinned_name),
|
||||
"define the local before the loop (dominates loop entry)",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,16 +176,20 @@ fn extract_depth_scan_shape(
|
||||
}
|
||||
|
||||
if !has_return_i {
|
||||
return Err(error_tags::freeze(
|
||||
"[phase107/balanced_depth_scan/contract/missing_return_i] missing `if depth == 0 { return i }` inside close branch",
|
||||
return Err(error_tags::freeze_with_hint(
|
||||
"phase107/balanced_depth_scan/missing_return_i",
|
||||
"missing `if depth == 0 { return i }` inside close branch",
|
||||
"ensure 'if depth == 0 { return i }' is inside close-branch",
|
||||
));
|
||||
}
|
||||
|
||||
// Require a tail `i = i + 1` at top-level (keeps the family narrow).
|
||||
let has_tail_inc = body.iter().any(|n| is_inc_assign(n, loop_counter_name, 1));
|
||||
if !has_tail_inc {
|
||||
return Err(error_tags::freeze(
|
||||
"[phase107/balanced_depth_scan/contract/missing_tail_inc] missing `i = i + 1` tail update",
|
||||
return Err(error_tags::freeze_with_hint(
|
||||
"phase107/balanced_depth_scan/missing_tail_inc",
|
||||
"missing `i = i + 1` tail update",
|
||||
"add tail update 'i = i + 1' at top-level",
|
||||
));
|
||||
}
|
||||
|
||||
@ -210,11 +214,15 @@ fn extract_depth_scan_shape(
|
||||
|
||||
fn scan_control_flow(node: &ASTNode, return_count: &mut usize) -> Result<(), String> {
|
||||
match node {
|
||||
ASTNode::Break { .. } => Err(error_tags::freeze(
|
||||
"[phase107/balanced_depth_scan/contract/unexpected_break] break is not allowed in this family (return-in-loop only)",
|
||||
ASTNode::Break { .. } => Err(error_tags::freeze_with_hint(
|
||||
"phase107/balanced_depth_scan/unexpected_break",
|
||||
"break is not allowed in this family (return-in-loop only)",
|
||||
"use 'return i' form (no break) in this family",
|
||||
)),
|
||||
ASTNode::Continue { .. } => Err(error_tags::freeze(
|
||||
"[phase107/balanced_depth_scan/contract/unexpected_continue] continue is not allowed in this family",
|
||||
ASTNode::Continue { .. } => Err(error_tags::freeze_with_hint(
|
||||
"phase107/balanced_depth_scan/unexpected_continue",
|
||||
"continue is not allowed in this family",
|
||||
"remove continue, use tail increment instead",
|
||||
)),
|
||||
ASTNode::Return { .. } => {
|
||||
*return_count += 1;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
//! - the digit literal set used in the final `if <is_digit> { ... } else { break }`
|
||||
|
||||
use crate::ast::{ASTNode, BinaryOperator, LiteralValue};
|
||||
use crate::mir::join_ir::lowering::error_tags;
|
||||
|
||||
pub(crate) struct ReadDigitsBreakConditionBox;
|
||||
|
||||
@ -33,7 +34,11 @@ impl ReadDigitsBreakConditionBox {
|
||||
}
|
||||
|
||||
let (ch_var, eos_cond) = find_eos_break_condition(body).ok_or_else(|| {
|
||||
"[phase104/read-digits] missing `if ch == \"\" { break }` guard".to_string()
|
||||
error_tags::freeze_with_hint(
|
||||
"phase104/read_digits/missing_eos_guard",
|
||||
"missing `if ch == \"\" { break }` guard",
|
||||
"add 'if ch == \"\" { break }' before digit check",
|
||||
)
|
||||
})?;
|
||||
|
||||
let mut digit_literals: Vec<String> = Vec::new();
|
||||
@ -60,9 +65,10 @@ impl ReadDigitsBreakConditionBox {
|
||||
// Phase 104 minimal: require the canonical digit set.
|
||||
let expected: Vec<String> = (0..=9).map(|d| d.to_string()).collect();
|
||||
if digit_literals != expected {
|
||||
return Err(format!(
|
||||
"[phase104/read-digits] digit condition literal set mismatch: got={:?}, expected={:?}",
|
||||
digit_literals, expected
|
||||
return Err(error_tags::freeze_with_hint(
|
||||
"phase104/read_digits/digit_set_mismatch",
|
||||
&format!("digit condition literal set mismatch: got={:?}, expected={:?}", digit_literals, expected),
|
||||
"use explicit 'ch == \"0\" || ... || ch == \"9\"'",
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user