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:
2025-12-22 03:33:30 +09:00
parent 5f891b72ad
commit 4ef2261e97
6 changed files with 157 additions and 20 deletions

View File

@ -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,
};