diff --git a/src/mir/builder/calls/unified_emitter.rs b/src/mir/builder/calls/unified_emitter.rs index c4605429..cdef6b5a 100644 --- a/src/mir/builder/calls/unified_emitter.rs +++ b/src/mir/builder/calls/unified_emitter.rs @@ -68,6 +68,11 @@ impl UnifiedCallEmitterBox { target: CallTarget, args: Vec, ) -> Result<(), String> { + // Phase 287 P4: Debug trace to see what CallTarget is passed + if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") { + eprintln!("[P287-TRACE] emit_unified_call_impl: target={:?}, dst={:?}, args={:?}", target, dst, args); + } + // Emit resolve.try for method targets (dev-only; default OFF) let arity_for_try = args.len(); if let CallTarget::Method { diff --git a/src/mir/builder/rewrite/known.rs b/src/mir/builder/rewrite/known.rs index c5a97e67..0c5d3eed 100644 --- a/src/mir/builder/rewrite/known.rs +++ b/src/mir/builder/rewrite/known.rs @@ -52,6 +52,22 @@ pub(crate) fn try_known_rewrite( if !builder.comp_ctx.user_defined_boxes.contains_key(cls) { // Phase 285LLVM-1.1: HashMap return None; } + + // Phase 287 P4: Don't rewrite for primitive types + // (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); + } + return None; + } + _ => {} + } + } + // Policy gates(従来互換) let allow_userbox_rewrite = std::env::var("NYASH_DEV_REWRITE_USERBOX").ok().as_deref() == Some("1"); @@ -127,6 +143,22 @@ pub(crate) fn try_known_rewrite_to_dst( if !builder.comp_ctx.user_defined_boxes.contains_key(cls) { // Phase 285LLVM-1.1: HashMap return None; } + + // Phase 287 P4: Don't rewrite for primitive types + // (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); + } + return None; + } + _ => {} + } + } + let allow_userbox_rewrite = std::env::var("NYASH_DEV_REWRITE_USERBOX").ok().as_deref() == Some("1"); let allow_new_origin = std::env::var("NYASH_DEV_REWRITE_NEW_ORIGIN") @@ -207,6 +239,22 @@ pub(crate) fn try_unique_suffix_rewrite( if !builder.comp_ctx.user_defined_boxes.contains_key(&id.box_name) { // Phase 285LLVM-1.1: HashMap return None; } + + // Phase 287 P4: Don't rewrite for primitive types + // (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); + } + return None; + } + _ => {} + } + } + // unified let mut call_args = Vec::with_capacity(arg_values.len() + 1); call_args.push(object_value); // 'me' @@ -263,6 +311,22 @@ pub(crate) fn try_unique_suffix_rewrite_to_dst( if !builder.comp_ctx.user_defined_boxes.contains_key(&id.box_name) { // Phase 285LLVM-1.1: HashMap return None; } + + // Phase 287 P4: Don't rewrite for primitive types + // (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); + } + return None; + } + _ => {} + } + } + let _name_const = match crate::mir::builder::name_const::make_name_const_result(builder, &fname) { Ok(v) => v, diff --git a/src/mir/builder/rewrite/special.rs b/src/mir/builder/rewrite/special.rs index c8d474b8..331e6040 100644 --- a/src/mir/builder/rewrite/special.rs +++ b/src/mir/builder/rewrite/special.rs @@ -161,6 +161,40 @@ pub(crate) fn try_early_str_like_to_dst( None => return None, }; if let Some(cls) = class_name_opt.clone() { + // Phase 287 P4: Conservative early rewrite guards + + if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") { + eprintln!("[P287-GUARD] try_early_str_like_to_dst: cls={}, object_value={:?}", cls, object_value); + eprintln!("[P287-GUARD] current_static_box={:?}", builder.comp_ctx.current_static_box()); + eprintln!("[P287-GUARD] value_type={:?}", builder.type_ctx.value_types.get(&object_value)); + } + + // Guard 1: Don't rewrite if class is current static box context + // (likely context contamination, not actual receiver type) + if let Some(current_box) = builder.comp_ctx.current_static_box() { + if cls == current_box { + if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") { + eprintln!("[P287-GUARD] -> Guard 1 BLOCKED: cls == current_static_box ({})", current_box); + } + return None; + } + } + + // Guard 2: Don't rewrite for primitive types + // (should use universal slot toString[#0]) + 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] -> Guard 2 BLOCKED: primitive type {:?}", recv_type); + } + return None; + } + _ => {} + } + } + let str_name = crate::mir::builder::calls::function_lowering::generate_method_function_name( &cls, "str", 0, );