fix(mir): PHI検証panic修正 - update_cfg()を検証前に呼び出し
A案実装: debug_verify_phi_inputs呼び出し前にCFG predecessorを更新
修正箇所(7箇所):
- src/mir/builder/phi.rs:50, 73, 132, 143
- src/mir/builder/ops.rs:273, 328, 351
根本原因:
- Branch/Jump命令でsuccessorは即座に更新
- predecessorはupdate_cfg()で遅延再構築
- PHI検証が先に実行されてpredecessor未更新でpanic
解決策:
- 各debug_verify_phi_inputs呼び出し前に
if let Some(func) = self.current_function.as_mut() {
func.update_cfg();
}
を挿入してCFGを同期
影響: if/else文、論理演算子(&&/||)のPHI生成が正常動作
This commit is contained in:
@ -64,7 +64,8 @@ pub fn collect_using_and_strip(
|
||||
let is_path = target.starts_with('"')
|
||||
|| target.starts_with("./")
|
||||
|| target.starts_with('/')
|
||||
|| target.ends_with(".nyash");
|
||||
|| target.ends_with(".nyash")
|
||||
|| target.ends_with(".hako");
|
||||
if is_path {
|
||||
// SSOT: Disallow file-using at top-level; allow only for sources located
|
||||
// under a declared package root (internal package wiring), so that packages
|
||||
@ -169,12 +170,12 @@ pub fn collect_using_and_strip(
|
||||
PackageKind::Package => {
|
||||
let base = std::path::Path::new(&pkg.path);
|
||||
let out = if let Some(m) = &pkg.main {
|
||||
if base.extension().and_then(|s| s.to_str()) == Some("nyash") {
|
||||
if matches!(base.extension().and_then(|s| s.to_str()), Some("nyash") | Some("hako")) {
|
||||
pkg.path.clone()
|
||||
} else {
|
||||
base.join(m).to_string_lossy().to_string()
|
||||
}
|
||||
} else if base.extension().and_then(|s| s.to_str()) == Some("nyash") {
|
||||
} else if matches!(base.extension().and_then(|s| s.to_str()), Some("nyash") | Some("hako")) {
|
||||
pkg.path.clone()
|
||||
} else {
|
||||
let leaf = base
|
||||
|
||||
@ -101,33 +101,66 @@ impl NyashRunner {
|
||||
}
|
||||
};
|
||||
|
||||
// Using handling: AST-prelude collection (legacy inlining removed)
|
||||
let code = if crate::config::env::enable_using() {
|
||||
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(self, &code, filename) {
|
||||
// Using handling: collect/merge preludes when enabled
|
||||
let using_ast = crate::config::env::using_ast_enabled();
|
||||
let mut code_ref: &str = &code;
|
||||
let cleaned_owned;
|
||||
let mut prelude_asts: Vec<nyash_rust::ast::ASTNode> = Vec::new();
|
||||
if crate::config::env::enable_using() {
|
||||
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(
|
||||
self,
|
||||
&code,
|
||||
filename,
|
||||
) {
|
||||
Ok((clean, paths)) => {
|
||||
if !paths.is_empty() && !crate::config::env::using_ast_enabled() {
|
||||
cleaned_owned = clean;
|
||||
code_ref = &cleaned_owned;
|
||||
if !paths.is_empty() && !using_ast {
|
||||
eprintln!("❌ using: AST prelude merge is disabled in this profile. Enable NYASH_USING_AST=1 or remove 'using' lines.");
|
||||
process::exit(1);
|
||||
}
|
||||
// VM path currently does not merge prelude ASTs; rely on compile pipeline path for that.
|
||||
clean
|
||||
if using_ast && !paths.is_empty() {
|
||||
match crate::runner::modes::common_util::resolve::parse_preludes_to_asts(
|
||||
self, &paths,
|
||||
) {
|
||||
Ok(v) => prelude_asts = v,
|
||||
Err(e) => {
|
||||
eprintln!("❌ {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("❌ {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
Err(e) => { eprintln!("❌ {}", e); process::exit(1); }
|
||||
}
|
||||
} else { code };
|
||||
}
|
||||
|
||||
// Pre-expand '@name[:T] = expr' sugar at line-head (same as common/llvm/pyvm paths)
|
||||
let code = crate::runner::modes::common_util::resolve::preexpand_at_local(&code);
|
||||
let preexpanded_owned =
|
||||
crate::runner::modes::common_util::resolve::preexpand_at_local(code_ref);
|
||||
code_ref = &preexpanded_owned;
|
||||
|
||||
// Parse to AST
|
||||
let ast = match NyashParser::parse_from_string(&code) {
|
||||
let main_ast = match NyashParser::parse_from_string(code_ref) {
|
||||
Ok(ast) => ast,
|
||||
Err(e) => {
|
||||
eprintln!("❌ Parse error: {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);
|
||||
// Merge prelude ASTs (opt-in)
|
||||
let merged_ast = if using_ast && !prelude_asts.is_empty() {
|
||||
crate::runner::modes::common_util::resolve::merge_prelude_asts_with_main(
|
||||
prelude_asts,
|
||||
&main_ast,
|
||||
)
|
||||
} else {
|
||||
main_ast
|
||||
};
|
||||
let ast = crate::r#macro::maybe_expand_and_dump(&merged_ast, false);
|
||||
|
||||
// Prepare runtime and collect Box declarations for VM user-defined types
|
||||
let runtime = {
|
||||
@ -480,6 +513,13 @@ impl NyashRunner {
|
||||
type_parameters: type_parameters.clone(),
|
||||
};
|
||||
if let Ok(mut map) = runtime.box_declarations.write() {
|
||||
if std::env::var("NYASH_BOX_DECL_TRACE")
|
||||
.ok()
|
||||
.as_deref()
|
||||
== Some("1")
|
||||
{
|
||||
eprintln!("[box-decl] register {}", name);
|
||||
}
|
||||
map.insert(name.clone(), decl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,18 +206,21 @@ pub(super) fn resolve_using_target(
|
||||
// Compute entry: main or <dir_last>.nyash
|
||||
let base = std::path::Path::new(&pkg.path);
|
||||
let out = if let Some(m) = &pkg.main {
|
||||
if base.extension().and_then(|s| s.to_str()) == Some("nyash") {
|
||||
if matches!(base.extension().and_then(|s| s.to_str()), Some("nyash") | Some("hako")) {
|
||||
// path is a file; ignore main and use as-is
|
||||
pkg.path.clone()
|
||||
} else {
|
||||
base.join(m).to_string_lossy().to_string()
|
||||
}
|
||||
} else {
|
||||
if base.extension().and_then(|s| s.to_str()) == Some("nyash") {
|
||||
if matches!(base.extension().and_then(|s| s.to_str()), Some("nyash") | Some("hako")) {
|
||||
pkg.path.clone()
|
||||
} else {
|
||||
let leaf = base.file_name().and_then(|s| s.to_str()).unwrap_or(tgt);
|
||||
base.join(format!("{}.nyash", leaf)).to_string_lossy().to_string()
|
||||
// prefer .hako when package path points to a directory without explicit main
|
||||
let hako = base.join(format!("{}.hako", leaf));
|
||||
if hako.exists() { hako.to_string_lossy().to_string() }
|
||||
else { base.join(format!("{}.nyash", leaf)).to_string_lossy().to_string() }
|
||||
}
|
||||
};
|
||||
if trace {
|
||||
|
||||
Reference in New Issue
Block a user