fix(rewrite): Limit primitive type guards to toString/stringify/str only (Phase 287 P4)

Critical fix: Previous guards blocked ALL primitive method calls, not just
toString/stringify/str. This would have broken length(), substring(), etc.

Root cause: Guards in known.rs checked primitive type but NOT method name,
so ANY method call on Integer/Float/Bool/String was blocked.

Fix: Added method name check to all 4 guard locations:
  if method == "toString" || method == "stringify" || method == "str" {
      // Only then check primitive type
  }

Modified functions in known.rs:
1. try_known_rewrite (line 58-71)
2. try_known_rewrite_to_dst (line 151-164)
3. try_unique_suffix_rewrite (line 249-262)
4. try_unique_suffix_rewrite_to_dst (line 323-336)

Verification:
- toString() still works: "1" output 
- MIR still uses boxcall (no Global call) 
- Other primitive methods (length/substring) NOT affected 

Credit: User caught this critical issue before it caused problems!

🎉 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-25 10:50:14 +09:00
parent 98a948344e
commit 716f5735df

View File

@ -53,18 +53,20 @@ pub(crate) fn try_known_rewrite(
return None;
}
// Phase 287 P4: Don't rewrite for primitive types
// Phase 287 P4: Don't rewrite for primitive types (toString/stringify/str only)
// (should use universal slot toString[#0], not user-defined static methods)
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_known_rewrite: BLOCKED primitive type {:?}", recv_type);
if method == "toString" || method == "stringify" || method == "str" {
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_known_rewrite: BLOCKED primitive type {:?} for {}", recv_type, method);
}
return None;
}
return None;
_ => {}
}
_ => {}
}
}
@ -144,18 +146,20 @@ pub(crate) fn try_known_rewrite_to_dst(
return None;
}
// Phase 287 P4: Don't rewrite for primitive types
// Phase 287 P4: Don't rewrite for primitive types (toString/stringify/str only)
// (should use universal slot toString[#0], not user-defined static methods)
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_known_rewrite_to_dst: BLOCKED primitive type {:?}", recv_type);
if method == "toString" || method == "stringify" || method == "str" {
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_known_rewrite_to_dst: BLOCKED primitive type {:?} for {}", recv_type, method);
}
return None;
}
return None;
_ => {}
}
_ => {}
}
}
@ -240,18 +244,20 @@ pub(crate) fn try_unique_suffix_rewrite(
return None;
}
// Phase 287 P4: Don't rewrite for primitive types
// Phase 287 P4: Don't rewrite for primitive types (toString/stringify/str only)
// (should use universal slot toString[#0], not user-defined static methods)
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_unique_suffix_rewrite: BLOCKED primitive type {:?}", recv_type);
if method == "toString" || method == "stringify" || method == "str" {
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_unique_suffix_rewrite: BLOCKED primitive type {:?} for {}", recv_type, method);
}
return None;
}
return None;
_ => {}
}
_ => {}
}
}
@ -312,18 +318,20 @@ pub(crate) fn try_unique_suffix_rewrite_to_dst(
return None;
}
// Phase 287 P4: Don't rewrite for primitive types
// Phase 287 P4: Don't rewrite for primitive types (toString/stringify/str only)
// (should use universal slot toString[#0], not user-defined static methods)
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_unique_suffix_rewrite_to_dst: BLOCKED primitive type {:?}", recv_type);
if method == "toString" || method == "stringify" || method == "str" {
if let Some(recv_type) = builder.type_ctx.value_types.get(&object_value) {
use crate::mir::MirType;
match recv_type {
MirType::Integer | MirType::Float | MirType::Bool | MirType::String => {
if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") {
eprintln!("[P287-GUARD] try_unique_suffix_rewrite_to_dst: BLOCKED primitive type {:?} for {}", recv_type, method);
}
return None;
}
return None;
_ => {}
}
_ => {}
}
}