## Phase 71-SSA: StageBDriverBox birth warning 解消 - Fixed false-positive dev verify warning for static boxes - StageBDriverBox is a static box, so it doesn't follow NewBox→birth pattern - Modified lifecycle.rs to skip StageBDriverBox from birth() requirement ## Phase 73-A: Stage-3 legacy ENV 統一化 - Consolidated NYASH_PARSER_STAGE3 and HAKO_PARSER_STAGE3 → NYASH_FEATURES=stage3 - Updated 20 test files (46 direct replacements) - Special handling for parser_stage3.rs compat layer and mir_static_main_args_loop.rs - All test files now use unified NYASH_FEATURES=stage3 ## Phase 72-73: ENV inventory documented - Created phase72-73-env-inventory.md with complete usage analysis - Identified 113 direct ENV reads requiring SSOT consolidation - Prioritized Phase 72 (JoinIR EXPERIMENT SSOT) and Phase 73 (Stage-3 cleanup) ## Phase 74-SSA: Minimal reproduction for static box delegation - Created parser_box_minimal.hako and ssa_static_delegation_min.hako - Investigated spawn failure in selfhost compiler (arguments too long) - Root cause: NYASH_NY_COMPILER_EMIT_ONLY=1 defaults to emit-only mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
83 lines
3.4 KiB
Rust
83 lines
3.4 KiB
Rust
//! Static box naming tests (Main._nop/0 canonicalization)
|
||
//!
|
||
//! Repro: apps/tests/minimal_to_i64_void.hako
|
||
//! - static box Main { _nop(); main(args) { me._nop(); ... } }
|
||
//! - VM runtime reported Unknown: main._nop/0
|
||
//! This test compiles the fixture and inspects the MIR module to ensure:
|
||
//! 1) Static methods are materialized as canonical names (Main._nop/0)
|
||
//! 2) Calls inside Main.main use the canonical/global name
|
||
|
||
use crate::ast::ASTNode;
|
||
use crate::mir::instruction::MirInstruction;
|
||
use crate::mir::{definitions::Callee, MirCompiler};
|
||
use crate::parser::NyashParser;
|
||
|
||
fn load_fixture_with_string_helpers() -> String {
|
||
// Bundle StringHelpers directly to avoid relying on using resolution in this unit test.
|
||
let string_helpers = include_str!("../../lang/src/shared/common/string_helpers.hako");
|
||
let fixture =
|
||
std::fs::read_to_string("apps/tests/minimal_to_i64_void.hako").expect("read fixture");
|
||
format!("{}\n\n{}", string_helpers, fixture)
|
||
}
|
||
|
||
/// Compile minimal_to_i64_void.hako and assert Main._nop/0 exists and is targeted.
|
||
/// The test now accepts either:
|
||
/// - Global(Main._nop/0) call (methodization OFF), or
|
||
/// - Method(Main._nop, receiver=singleton) call (methodization ON: default)
|
||
/// Methodization is ON by default (HAKO_MIR_BUILDER_METHODIZE=1).
|
||
#[test]
|
||
fn mir_static_main_box_emits_canonical_static_methods() {
|
||
// Enable Stage‑3 + using for the fixture.
|
||
std::env::set_var("NYASH_FEATURES", "stage3");
|
||
std::env::set_var("NYASH_FEATURES", "stage3");
|
||
std::env::set_var("NYASH_PARSER_ALLOW_SEMICOLON", "1");
|
||
std::env::set_var("NYASH_ENABLE_USING", "1");
|
||
std::env::set_var("HAKO_ENABLE_USING", "1");
|
||
|
||
let src = load_fixture_with_string_helpers();
|
||
let ast: ASTNode = NyashParser::parse_from_string(&src).expect("parse");
|
||
|
||
let mut mc = MirCompiler::with_options(false);
|
||
let compiled = mc.compile(ast).expect("compile");
|
||
|
||
// 1) Ensure Main._nop/0 is materialized in the function table.
|
||
let mut fn_names: Vec<String> = compiled.module.functions.keys().cloned().collect();
|
||
fn_names.sort();
|
||
assert!(
|
||
fn_names.iter().any(|n| n == "Main._nop/0"),
|
||
"Main._nop/0 missing. Functions:\n{}",
|
||
fn_names.join("\n")
|
||
);
|
||
|
||
// 2) At least keep the static method materialized (methodization may inline calls away).
|
||
assert!(
|
||
fn_names.iter().any(|n| n == "Main._nop/0"),
|
||
"Main._nop/0 should remain materialized even if calls are optimized away"
|
||
);
|
||
}
|
||
|
||
/// Execute the minimal fixture with Void-returning _nop() and confirm it lowers without SSA/arity drift.
|
||
#[test]
|
||
fn mir_static_main_box_executes_void_path_with_guard() {
|
||
std::env::set_var("NYASH_FEATURES", "stage3");
|
||
std::env::set_var("NYASH_FEATURES", "stage3");
|
||
std::env::set_var("NYASH_PARSER_ALLOW_SEMICOLON", "1");
|
||
std::env::set_var("NYASH_ENABLE_USING", "1");
|
||
std::env::set_var("HAKO_ENABLE_USING", "1");
|
||
|
||
// Accept Void inputs as 0 for this execution path.
|
||
std::env::set_var("NYASH_TO_I64_FORCE_ZERO", "1");
|
||
|
||
let src = load_fixture_with_string_helpers();
|
||
let ast: ASTNode = NyashParser::parse_from_string(&src).expect("parse");
|
||
|
||
let mut mc = MirCompiler::with_options(false);
|
||
let compiled = mc.compile(ast).expect("compile");
|
||
|
||
// Just ensure the symbol exists; methodization may optimize away the actual call.
|
||
assert!(
|
||
compiled.module.functions.keys().any(|k| k == "Main._nop/0"),
|
||
"Main._nop/0 should remain defined"
|
||
);
|
||
}
|