Files
hakorune/src/mir/join_ir/lowering/mod.rs

351 lines
13 KiB
Rust
Raw Normal View History

//! JoinIR Lowering Functions
//!
//! Phase 27.9: Modular separation of MIR → JoinIR lowering implementations.
//!
//! このモジュールは各種 MIR 関数を JoinIR に変換する lowering 関数を提供します。
//!
//! ## 構成:
//! - `common.rs`: CFG sanity checks と lowering 共通ユーティリティPhase 27.10
//! - `value_id_ranges.rs`: ValueId 範囲管理Phase 27.13+
//! - `min_loop.rs`: JoinIrMin.main/0 専用の最小ループ lowering
//! - `skip_ws.rs`: Main.skip/1 の空白スキップ lowering手書き版MIR自動解析版
//! - `funcscanner_trim.rs`: FuncScannerBox.trim/1 の trim lowering
//! - `stage1_using_resolver.rs`: Stage1UsingResolverBox.resolve_for_source entries loop loweringPhase 27.12
//! - `funcscanner_append_defs.rs`: FuncScannerBox._append_defs/2 の配列結合 loweringPhase 27.14
//! - `if_select.rs`: Phase 33 If/Else → Select lowering
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
//! - `if_dry_runner.rs`: Phase 33-10 If lowering dry-run スキャナー(箱化版)
pub mod common;
pub mod exit_args_resolver;
pub mod funcscanner_append_defs;
pub mod funcscanner_trim;
pub mod generic_case_a;
pub mod generic_type_resolver; // Phase 66: P3-C ジェネリック型推論箱
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
pub mod if_dry_runner; // Phase 33-10.0
pub mod if_merge; // Phase 33-7
pub mod if_phi_context; // Phase 61-1
feat(joinir): Phase 61-2 If-in-loop JoinIR dry-run検証インフラ実装 ## 実装内容 ### 61-2.1: dry-runフラグ追加 - `src/config/env.rs`: joinir_if_in_loop_dryrun_enabled() 追加 (+11行) - `HAKO_JOINIR_IF_IN_LOOP_DRYRUN=1` でdry-runモード有効化 ### 61-2.2: loop_builder.rs dry-run統合 - `src/mir/loop_builder.rs`: JoinIR PhiSpec計算とA/B比較実装 (+47行) - JoinInst取得時にPhiSpec保存、PhiBuilderBox実行後に比較 ### 61-2.3: PhiSpec計算ロジック実装 - `src/mir/join_ir/lowering/if_phi_spec.rs`: 新規作成 (+203行) - PhiSpec構造体(header_phis/exit_phis) - compute_phi_spec_from_joinir(): JoinInstからPHI仕様計算 - extract_phi_spec_from_builder(): PhiBuilderBox結果抽出 - compare_and_log_phi_specs(): A/B比較とログ出力 - BTreeMap/BTreeSet使用(決定的イテレーション保証) ### 61-2.4: A/B比較テスト実装 - `src/tests/phase61_if_in_loop_dryrun.rs`: 新規作成 (+49行) - phase61_2_dry_run_flag_available: フラグ動作確認 - phase61_2_phi_spec_creation: PhiSpec構造体テスト - テスト結果: ✅ 2/2 PASS ## テスト結果 - Phase 61-2新規テスト: ✅ 2/2 PASS - 既存loopformテスト: ✅ 14/14 PASS(退行なし) - ビルド: ✅ 成功(エラー0件) ## コード変更量 +312行(env.rs: +11, if_phi_spec.rs: +203, loop_builder.rs: +47, tests: +49, その他: +2) ## 技術的成果 1. PhiSpec構造体完成(JoinIR/PhiBuilderBox統一表現) 2. dry-run検証インフラ(本番動作に影響なし) 3. BTreeMap統一(Option C知見活用) ## 次のステップ(Phase 61-3) - dry-run → 本番経路への昇格 - PhiBuilderBox If側メソッド削除(-226行) - JoinIR経路のみでif-in-loop PHI生成 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:26:02 +09:00
pub mod if_phi_spec; // Phase 61-2
pub mod if_select; // Phase 33
pub mod loop_form_intake;
pub mod loop_scope_shape;
pub mod loop_to_join;
pub mod min_loop;
pub mod skip_ws;
pub mod stage1_using_resolver;
pub mod stageb_body;
pub mod stageb_funcscanner;
feat(joinir): Phase 65.5 TypeHintPolicy箱化モジュール化 ## 目的 lifecycle.rs の型ヒント判定ロジックを箱化モジュール化し、 単一責務原則に基づいたクリーンなアーキテクチャを実現。 ## 主な変更 ### 新規ファイル - **type_hint_policy.rs** (237行): 型ヒントポリシー専用モジュール - `TypeHintPolicy` 構造体: 型ヒント対象関数の判定 - `is_target()`: P1/P2/P3-A/P3-B 統合判定 - `extract_phi_type_hint()`: PHI から型ヒント抽出 - 7つの単体テスト(パターン別カバレッジ) ### 既存ファイル修正 - **lifecycle.rs**: 60行削減 - `get_phi_type_hint()` 削除 → `TypeHintPolicy::extract_phi_type_hint()` に移行 - `is_type_hint_target()` 削除 → `TypeHintPolicy::is_target()` に移行 - 2箇所の呼び出し箇所を TypeHintPolicy 使用に更新 - **lowering/mod.rs**: type_hint_policy モジュール宣言追加 ## 箱化の利点 - ✅ 単一責務:ポリシー判定のみを担当 - ✅ テスト可能:独立した単体テスト(7テスト) - ✅ 拡張容易:Phase 66+ で P3-C 追加が簡単 - ✅ 可読性向上:関数型スタイル(flat_map/find_map) ## テスト結果 ``` running 6 tests test type_hint_policy::tests::test_is_p1_target ... ok test type_hint_policy::tests::test_is_p2_target ... ok test type_hint_policy::tests::test_is_p3a_target ... ok test type_hint_policy::tests::test_is_p3b_target ... ok test type_hint_policy::tests::test_is_target ... ok test type_hint_policy::tests::test_p2_p3a_overlap ... ok ``` ## Phase 65 完了状況 - ✅ Phase 65-1: 型マッピング設計文書作成 - ✅ Phase 65-2-A: StringBox メソッド型ヒント実装 - ✅ Phase 65-2-B: Box コンストラクタ型ヒント実装 - ✅ Phase 65-3: lifecycle.rs への P3-A/B 統合 - ✅ Phase 65-4/65-5: 削除条件 5/5 達成、if_phi.rs を P3-C フォールバックに位置づけ - ✅ Phase 65.5: TypeHintPolicy 箱化モジュール化(今回) 🎉 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 06:37:34 +09:00
pub mod type_hint_policy; // Phase 65.5: 型ヒントポリシー箱化
pub mod type_inference; // Phase 65-2-A
pub mod value_id_ranges;
// Re-export public lowering functions
pub use funcscanner_append_defs::lower_funcscanner_append_defs_to_joinir;
pub use funcscanner_trim::lower_funcscanner_trim_to_joinir;
// Phase 31: LoopToJoinLowerer 統一箱
pub use loop_to_join::LoopToJoinLowerer;
// Phase 30 F-3: 旧 lower_case_a_loop_to_joinir_for_minimal_skip_ws は _with_scope に置き換え済みのため削除
pub use min_loop::lower_min_loop_to_joinir;
pub use skip_ws::lower_skip_ws_to_joinir;
pub use stage1_using_resolver::lower_stage1_usingresolver_to_joinir;
pub use stageb_body::lower_stageb_body_to_joinir;
pub use stageb_funcscanner::lower_stageb_funcscanner_to_joinir;
// Phase 33: If/Else → Select lowering entry point
use crate::mir::join_ir::JoinInst;
use crate::mir::{BasicBlockId, MirFunction};
/// Phase 33-9.1: Loop lowering対象関数の判定
///
/// これらの関数は Phase 32/33 で LoopToJoinLowerer によって処理されます。
/// If lowering (Select/IfMerge) の対象から除外することで、Loop/If の責務を明確に分離します。
///
/// ## 対象関数6本
/// - Main.skip/1: 空白スキップループ
/// - FuncScannerBox.trim/1: 前後空白削除ループ
/// - FuncScannerBox.append_defs/2: 配列結合ループ
/// - Stage1UsingResolverBox.resolve_for_source/5: using解析ループ
/// - StageBBodyExtractorBox.build_body_src/2: Stage-B本体抽出ループ
/// - StageBFuncScannerBox.scan_all_boxes/1: Stage-B Box走査ループ
///
/// ## 将来の拡張
/// NYASH_JOINIR_LOWER_GENERIC=1 で汎用 Case-A ループにも拡張可能
pub(crate) fn is_loop_lowered_function(name: &str) -> bool {
const LOOP_LOWERED_FUNCTIONS: &[&str] = &[
"Main.skip/1",
"FuncScannerBox.trim/1",
"FuncScannerBox.append_defs/2",
"Stage1UsingResolverBox.resolve_for_source/5",
"StageBBodyExtractorBox.build_body_src/2",
"StageBFuncScannerBox.scan_all_boxes/1",
];
LOOP_LOWERED_FUNCTIONS.contains(&name)
}
// ============================================================================
// Phase 80: JoinIR Mainline Unification - Core ON 時の本線化判定
// ============================================================================
/// Phase 80: JoinIR 本線化対象Loopの判定
///
/// `joinir_core_enabled()=true` の時、これらの関数のループは
/// 必ず JoinIR → MIR 経路を本線として試行します。
pub fn is_loop_mainline_target(name: &str) -> bool {
is_loop_lowered_function(name)
}
/// Phase 80: JoinIR 本線化対象Ifの判定
///
/// `joinir_core_enabled()=true` の時、これらの関数の if/else は
/// 必ず JoinIR → MIR 経路を本線として試行します。
pub fn is_if_mainline_target(name: &str) -> bool {
is_joinir_if_toplevel_target(name)
}
/// Phase 80: Core ON 時に JoinIR を本線として試行すべきか判定
///
/// Returns true if:
/// - `joinir_core_enabled()=true` AND
/// - 関数が本線化対象 (Loop or If)
pub fn should_try_joinir_mainline(func_name: &str, is_loop: bool) -> bool {
if !crate::config::env::joinir_core_enabled() {
return false;
}
if is_loop {
is_loop_mainline_target(func_name)
} else {
is_if_mainline_target(func_name)
}
}
/// Phase 80/81: Strict モードで JoinIR lowering 失敗時にパニックすべきか判定
pub fn should_panic_on_joinir_failure(func_name: &str, is_loop: bool) -> bool {
if !crate::config::env::joinir_strict_enabled() {
return false;
}
should_try_joinir_mainline(func_name, is_loop)
}
/// Phase 61-4: ループ外 If の JoinIR 対象関数判定
///
/// HAKO_JOINIR_IF_TOPLEVEL=1 有効時に、ループ外 if の JoinIR 経路を試行する関数。
/// 段階的に対象を拡大するため、最小限のホワイトリストから開始。
///
/// ## 対象関数
/// - IfSelectTest.*: テスト専用関数群
/// - IfToplevelTest.*: ループ外 if テスト専用Phase 61-4
/// - JsonShapeToMap._read_value_from_pair/1: Phase 33-4 で検証済み
///
/// ## 使用方法
/// if_form.rs から呼び出され、関数名がホワイトリストに含まれる場合のみ
/// JoinIR 経路を試行する。
pub fn is_joinir_if_toplevel_target(name: &str) -> bool {
// Test prefixes (always enabled)
if name.starts_with("IfSelectTest.")
|| name.starts_with("IfToplevelTest.")
|| name.starts_with("IfMergeTest.")
{
return true;
}
// Explicit approvals (Phase 33-4 verified)
matches!(
name,
"JsonShapeToMap._read_value_from_pair/1"
| "Stage1JsonScannerBox.value_start_after_key_pos/2"
)
}
/// Phase 33-7: Try to lower if/else to JoinIR Select/IfMerge instruction
///
/// Scope:
/// - Only applies to whitelisted functions:
/// - IfSelectTest.* (Phase 33-2/33-3)
/// - IfMergeTest.* (Phase 33-7)
/// - JsonShapeToMap._read_value_from_pair/1 (Phase 33-4 Stage-1)
/// - Stage1JsonScannerBox.value_start_after_key_pos/2 (Phase 33-4 Stage-B)
/// - Requires JoinIR If-select toggle (HAKO_JOINIR_IF_SELECT / joinir_if_select_enabled)
/// - Falls back to traditional if_phi on pattern mismatch
///
/// Pattern selection:
/// - 1 variable → Select
/// - 2+ variables → IfMerge
///
/// Phase 61-1: If-in-loop support
/// - `context` parameter: If-in-loop context (carrier_names for loop variables)
/// - None = Pure If, Some(_) = If-in-loop
///
/// Returns Some(JoinInst::Select) or Some(JoinInst::IfMerge) if pattern matched, None otherwise.
pub fn try_lower_if_to_joinir(
func: &MirFunction,
block_id: BasicBlockId,
debug: bool,
context: Option<&if_phi_context::IfPhiContext>, // Phase 61-1: If-in-loop context
) -> Option<JoinInst> {
// 1. dev/Core トグルチェック
//
// - Core: joinir_core_enabled() / joinir_if_select_enabled()
// - Dev: joinir_dev_enabled()(詳細ログ等)
//
// 実際の挙動切り替えは joinir_if_select_enabled() に集約し、
// Core/Dev ポリシーは config::env 側で判定する。
if !crate::config::env::joinir_if_select_enabled() {
return None;
}
let core_on = crate::config::env::joinir_core_enabled();
let strict_on = crate::config::env::joinir_strict_enabled();
// Phase 33-9.1: Loop専任関数の除外Loop/If責務分離
// Loop lowering対象関数はIf loweringの対象外にすることで、
// 1関数につき1 loweringの原則を保証します
if is_loop_lowered_function(&func.signature.name) {
return None;
}
// Phase 33-8: デバッグログレベル取得0-3
let debug_level = crate::config::env::joinir_debug_level();
let _debug = debug || debug_level >= 1;
// 2. Phase 33-8: 関数名ガード拡張(テスト + Stage-1 rollout + 明示承認)
let is_allowed =
// Test functions (always enabled)
func.signature.name.starts_with("IfSelectTest.") ||
feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論 **Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring 呼び出しを通すことに成功。 ## 主要変更 ### 1. MethodCall 構造追加 (34-6.1) - `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines) - 構造: `{ dst, receiver, method, args }` - 設計原則: JoinIR は構造のみ、意味論は MIR レベル ### 2. extract_value 更新 (34-6.2) - `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines) - receiver/args を extract_value で再帰処理 - ダミー Const(0) 削除 → 本物の MethodCall 生成 - cond 処理修正: ValueId(0) ハードコード → extract_value で取得 ### 3. JoinIR→MIR 変換実装 (34-6.3) - `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines) - `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines) - `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines) ### 4. テスト更新 (34-6.4) - `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造 - `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用 - テスト成功: v="hello", at=3 → "hel" ✅ ## 成果 - ✅ テスト全通過(1 passed; 0 failed) - ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル - ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用 **ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 17:05:46 +09:00
func.signature.name.starts_with("IfSelectLocalTest.") || // Phase 33-10 test
func.signature.name.starts_with("IfMergeTest.") ||
func.signature.name.starts_with("IfToplevelTest.") || // Phase 61-4: loop-outside if test
func.signature.name.starts_with("Stage1JsonScannerTestBox.") || // Phase 33-5 test
// Stage-1 rollout (env-controlled)
(crate::config::env::joinir_stage1_enabled() &&
func.signature.name.starts_with("Stage1")) ||
// Explicit approvals (Phase 33-4で検証済み, always on)
matches!(func.signature.name.as_str(),
"JsonShapeToMap._read_value_from_pair/1" |
"Stage1JsonScannerBox.value_start_after_key_pos/2"
);
// Phase 80: Core ON のときは許可リストを「JoinIRをまず試す」対象とみなす。
// Core OFF のときは従来どおり whitelist + env に頼る。
if !is_allowed || !core_on {
// Core OFF かつ許可外なら従来のガードでスキップ
if !is_allowed {
if debug_level >= 2 {
eprintln!(
"[try_lower_if_to_joinir] skipping non-allowed function: {}",
func.signature.name
);
}
return None;
}
}
let strict_allowed = strict_on && core_on && is_allowed;
if debug_level >= 1 {
eprintln!(
"[try_lower_if_to_joinir] trying to lower {}",
func.signature.name
);
}
// 3. Phase 33-7: IfMerge を優先的に試行(複数変数パターン)
// IfMerge が成功すればそれを返す、失敗したら Select を試行
// Phase 61-1: context がある場合は with_context() を使用
let if_merge_lowerer = if let Some(ctx) = context {
if_merge::IfMergeLowerer::with_context(debug_level, ctx.clone())
} else {
if_merge::IfMergeLowerer::new(debug_level)
};
if if_merge_lowerer.can_lower_to_if_merge(func, block_id) {
if let Some(result) = if_merge_lowerer.lower_if_to_if_merge(func, block_id) {
if debug_level >= 1 {
eprintln!(
"[try_lower_if_to_joinir] ✅ IfMerge lowering used for {}",
func.signature.name
);
}
return Some(result);
}
}
// 4. IfMerge が失敗したら Select を試行(単一変数パターン)
// Phase 61-1: context がある場合は with_context() を使用
let if_select_lowerer = if let Some(ctx) = context {
if_select::IfSelectLowerer::with_context(debug_level, ctx.clone())
} else {
if_select::IfSelectLowerer::new(debug_level)
};
if !if_select_lowerer.can_lower_to_select(func, block_id) {
if debug_level >= 1 {
eprintln!(
"[try_lower_if_to_joinir] pattern not matched for {}",
func.signature.name
);
}
if strict_allowed {
panic!(
"[joinir/if] strict mode: pattern not matched for {}",
func.signature.name
);
}
return None;
}
let result = if_select_lowerer.lower_if_to_select(func, block_id);
if result.is_some() && debug_level >= 1 {
eprintln!(
"[try_lower_if_to_joinir] ✅ Select lowering used for {}",
func.signature.name
);
}
if result.is_none() && strict_allowed {
panic!(
"[joinir/if] strict mode: lowering failed for {}",
func.signature.name
);
}
result
}
#[cfg(test)]
mod tests {
use super::*;
/// Phase 33-9.1: is_loop_lowered_function() の動作確認
#[test]
fn test_is_loop_lowered_function() {
// Loop 専任関数6本は true を返す
assert!(is_loop_lowered_function("Main.skip/1"));
assert!(is_loop_lowered_function("FuncScannerBox.trim/1"));
assert!(is_loop_lowered_function("FuncScannerBox.append_defs/2"));
assert!(is_loop_lowered_function(
"Stage1UsingResolverBox.resolve_for_source/5"
));
assert!(is_loop_lowered_function(
"StageBBodyExtractorBox.build_body_src/2"
));
assert!(is_loop_lowered_function(
"StageBFuncScannerBox.scan_all_boxes/1"
));
// If lowering 対象関数は false を返す
assert!(!is_loop_lowered_function("IfSelectTest.simple_return/0"));
assert!(!is_loop_lowered_function("IfMergeTest.multiple_true/0"));
assert!(!is_loop_lowered_function(
"JsonShapeToMap._read_value_from_pair/1"
));
assert!(!is_loop_lowered_function(
"Stage1JsonScannerBox.value_start_after_key_pos/2"
));
// 一般的な関数も false を返す
assert!(!is_loop_lowered_function("SomeBox.some_method/3"));
assert!(!is_loop_lowered_function("Main.main/0"));
}
}