fix(joinir): Phase 269 P1.2 - static call normalization for this.method()
Problem: - `this.method()` calls in static box loops were using string constant "StringUtils" as receiver - This violated Box Theory (static box this should not be runtime object) - Pattern8 was trying to pass receiver to JoinIR, causing SSA/PHI issues Solution (3-part fix): 1. **MeResolverBox Fail-Fast** (stmts.rs): Remove string fallback, error message cleanup 2. **ReceiverNormalizeBox** (calls/build.rs): Normalize `this/me.method()` → static call at compile-time 3. **Pattern8 Skip Static Box** (pattern8_scan_bool_predicate.rs): Reject Pattern8 for static box contexts Key changes: - **stmts.rs**: Update error message - remove MeBindingInitializerBox mentions - **calls/build.rs**: Add This/Me receiver check, normalize to static call if current_static_box exists - **calls/lowering.rs**: Remove NewBox-based "me" initialization (2 locations - fixes Stage1Cli regression) - **pattern8_scan_bool_predicate.rs**: Skip Pattern8 for static boxes (use Pattern1 fallback instead) Result: - ✅ phase269_p1_2_this_method_in_loop_vm.sh PASS (exit=7) - ✅ No regression: phase259_p0_is_integer_vm PASS - ✅ No regression: phase269_p0_pattern8_frag_vm PASS - ✅ Stage1Cli unit tests PASS - ✅ MIR uses CallTarget::Global, no const "StringUtils" as receiver 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -56,7 +56,21 @@ struct BoolPredicateScanParts {
|
||||
|
||||
/// Phase 269 P1: Detection for Pattern 8 (BoolPredicateScan)
|
||||
/// Now uses EdgeCFG Frag lowering via emission entrypoint
|
||||
pub(crate) fn can_lower(_builder: &MirBuilder, ctx: &super::router::LoopPatternContext) -> bool {
|
||||
/// Phase 269 P1.2: Skip Pattern8 for static box this.method() - let ReceiverNormalizeBox handle
|
||||
pub(crate) fn can_lower(builder: &MirBuilder, ctx: &super::router::LoopPatternContext) -> bool {
|
||||
// Phase 269 P1.2: Skip Pattern8 for static box contexts
|
||||
// this.method() in static boxes should be normalized to static calls by ReceiverNormalizeBox
|
||||
// Pattern8 requires a receiver object, which doesn't exist for static box methods
|
||||
if builder.comp_ctx.current_static_box.is_some() {
|
||||
if ctx.debug {
|
||||
trace::trace().debug(
|
||||
"pattern8/can_lower",
|
||||
"reject: static box context (ReceiverNormalizeBox handles this.method())",
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
match extract_bool_predicate_scan_parts(ctx.condition, ctx.body) {
|
||||
Ok(Some(_)) => {
|
||||
if ctx.debug {
|
||||
@ -159,10 +173,16 @@ fn extract_bool_predicate_scan_parts(
|
||||
{
|
||||
// Extract receiver (e.g., "me")
|
||||
// Phase 259 P0: Support both Variable and Me node
|
||||
// Phase 269 P1.2: Skip This in static box context (handled by ReceiverNormalizeBox)
|
||||
// IMPORTANT: Me is registered as "me" in variable_map (not "this")
|
||||
let receiver = match object.as_ref() {
|
||||
ASTNode::Variable { name, .. } => name.clone(),
|
||||
ASTNode::Me { .. } => "me".to_string(), // Me is registered as "me" in MirBuilder
|
||||
ASTNode::This { .. } => {
|
||||
// Phase 269 P1.2: Skip pattern for This in static box context
|
||||
// Let ReceiverNormalizeBox handle static call normalization instead
|
||||
continue;
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user