diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index adf2f914..79aa40d4 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -40,6 +40,80 @@ ## 1. 最近完了した重要タスク +### 1-00w. Phase 30 F-3 レガシー削除 — 旧API関数とCaseAContext::new削除(**完了** 2025-11-25) + +**目的** +- F-3.0 で `_with_scope` パターンに全lowererが移行完了したため、不要になった旧API関数を削除 +- `CaseAContext::new()` を削除し、`from_scope()` のみに統一 + +**削除内容** +1. **generic_case_a.rs**: 旧API関数4個と未使用import削除 + - `lower_case_a_loop_to_joinir_for_minimal_skip_ws` + - `lower_case_a_loop_to_joinir_for_trim_minimal` + - `lower_case_a_loop_to_joinir_for_append_defs_minimal` + - `lower_case_a_loop_to_joinir_for_stage1_usingresolver_minimal` + - 未使用import: `LoopForm`, `LoopExitLivenessBox`, `LoopVarClassBox`, `MirFunction`, `MirQuery` +2. **loop_scope_shape.rs**: `CaseAContext::new()` 関数(約85行)削除 + - 未使用import: `intake_loop_form`, `MirFunction` +3. **mod.rs**: `pub use generic_case_a::lower_case_a_loop_to_joinir_for_minimal_skip_ws;` 削除 +4. **`#[allow(dead_code)]`除去**: 5関数から除去(現在使用中のため不要に) + +**成果**: ビルド警告ゼロ、コードサイズ削減約150行 + +--- + +### 1-00x. Phase 30 F-2.0 — PHI 箱インベントリ作成と削除順計画(**完了** 2025-11-25) + +**目的** +- PHI 関連の箱・モジュールを一覧化 +- 「どの箱をどの順番で消すか」を PHI_BOX_INVENTORY.md に記録 +- コード削除はまだ行わず、設計と棚卸しのみ + +**成果物** +1. **PHI_BOX_INVENTORY.md 作成**: `docs/private/roadmap2/phases/phase-30-final-joinir-world/` + - 一覧テーブル: 13箱 + 補助構造体11個 + - 削除順ポリシー: 早期/中期/最終の3段階 + - 外部依存箇所: loop_builder.rs, json_v0_bridge, join_ir/lowering +2. **TASKS.md 更新**: F-2.0 完了、F-2.1〜F-2.3 再整理 + +**削除順ポリシー要約**: +1. **早期削除** (F-2.1): HeaderPhiBuilder / ExitPhiBuilder / BodyLocalPhiBuilder / LoopPhiManager + - 外部呼び出しがテストのみ、JoinIR で完全代替済み +2. **中期削除** (F-2.2): PhiBuilderBox / LoopSnapshotMerge / if_phi 等 + - F-3/F-4 完了後に削除 +3. **最終削除** (F-2.3): LoopVarClassBox / LoopExitLivenessBox / LocalScopeInspectorBox + - LoopScopeShape 完全移行後に削除 + +**次手**: F-2.1 以降で早期削除候補から順に削除開始 + +--- + +### 1-00y. Phase 30 F-3.0 — skip_ws で LoopScopeShape 実データ運用開始(**完了** 2025-11-25) + +**目的** +- LoopScopeShape を lowering で実データ運用に切り替える(skip_ws を最初のケースとして) +- `_with_scope + *_core` パターンを確立し、他の lowerer(trim/append_defs/Stage-1)に展開する準備 + +**成果物** +1. **generic_case_a.rs 更新**: + - `lower_case_a_skip_ws_with_scope(scope: LoopScopeShape)` 新関数追加 + - `lower_case_a_skip_ws_core(ctx: &CaseAContext)` 共通ロジック抽出 + - 既存の `lower_case_a_loop_to_joinir_for_minimal_skip_ws` は `*_core` に委譲する薄いラッパーに +2. **CaseAContext::from_scope() API**: LoopScopeShape を直接受け取り、CaseAContext を構築 +3. **コード品質向上**: + - 未使用インポート削除(BinaryOperator, VarId) + - Phase 30 準備コードに `#[allow(dead_code)]` 追加 + - visibility 修正(`pub` → `pub(crate)`)で警告ゼロ達成 + +**確立されたパターン**: +``` +LoopScopeShape → CaseAContext::from_scope() → lower_case_a_X_core() → JoinModule +``` + +**次手**: trim / append_defs / Stage-1 minimal に同じパターンを広げていく + +--- + ### 1-00z. Phase 30 F-1/F-3/F-4.4 準備調査 — generic_case_a 本線化準備(**完了** 2025-11-25) **目的** @@ -47,25 +121,29 @@ - Task B: VM runner のハードコード分岐の縮退計画を TASKS.md F-4.4 に追記 - Task C: 本セクションとして CURRENT_TASK.md に橋渡しを記録 -**調査結果: Lowerer ファイルの Case A 対応状況** +**調査結果: Lowerer ファイルの Case A 対応状況**(2025-11-25 更新) | ファイル | generic_case_a 呼び出し | LoopScopeShape 使用 | 状態 | |---------|------------------------|-------------------|------| -| skip_ws.rs | ✅ `lower_case_a_loop_to_joinir_for_minimal_skip_ws` | ❌(空Box渡し) | 実装済み | -| funcscanner_trim.rs | ✅ `lower_case_a_loop_to_joinir_for_trim_minimal` | ❌(空Box渡し) | 実装済み | -| funcscanner_append_defs.rs | ✅ `lower_case_a_loop_to_joinir_for_append_defs_minimal` | ❌(空Box渡し) | 実装済み | -| stage1_using_resolver.rs | ✅ `lower_case_a_loop_to_joinir_for_stage1_usingresolver_minimal` | ❌(空Box渡し) | 実装済み | +| skip_ws.rs | ✅ `lower_case_a_skip_ws_with_scope` | ✅ `_with_scope` 配線済み | **F-3.0 完了** | +| funcscanner_trim.rs | ✅ `lower_case_a_trim_with_scope` | ✅ `_with_scope` 配線済み | **F-3.0.3 完了** | +| funcscanner_append_defs.rs | ✅ `lower_case_a_append_defs_with_scope` | ✅ `_with_scope` 配線済み | **F-3.0.4 完了** | +| stage1_using_resolver.rs | ✅ `lower_case_a_stage1_usingresolver_with_scope` | ✅ `_with_scope` 配線済み | **F-3.0.5 完了** | | stageb_body.rs | ❌(プレースホルダのみ) | ❌ | 未実装 | | stageb_funcscanner.rs | ❌(プレースホルダのみ) | ❌ | 未実装 | **発見事項** 1. 全ファイルで `NYASH_JOINIR_LOWER_GENERIC` 環境変数トグル + `is_simple_case_a_loop()` で Case A 判定 -2. **全ファイルで LoopScopeShape 未使用** — `LoopVarClassBox::new()` と `LoopExitLivenessBox::new()`(空)が渡されている -3. `CaseAContext` は既に LoopScopeShape への移行準備完了(コメントで言及) +2. **skip_ws / trim / append_defs / Stage-1 の4箇所で LoopScopeShape 実データ運用開始**(F-3.0.2~3.0.5 完了) +3. `CaseAContext::from_scope()` API 確立 — LoopScopeShape を直接受け取り 4. stageb_body / stageb_funcscanner は generic_case_a 実装がない(プレースホルダのみ) -**次手(F-3/F-4.4 の一歩目)** -- F-3 方向: LoopScopeShape を `from_existing_boxes()` 経由で構築し、各 lowerer の空Box渡しを置換 +**次手(F-3/F-4.4 の継続)** +- ✅ F-3.0.2: skip_ws で `_with_scope` パターン確立 → **完了** +- ✅ F-3.0.3: trim 用 `_with_scope` 実装と呼び出し切り替え → **完了** (2025-11-25) +- ✅ F-3.0.4: append_defs 用 `_with_scope` 実装と切り替え → **完了** (2025-11-25) +- ✅ F-3.0.5: Stage-1 minimal 用 `_with_scope` 実装と切り替え → **完了** (2025-11-25) +- F-3.0.6:(必要なら)StageB minimal 用 `_with_scope` - F-4.4 方向: VM runner の関数名分岐(約90行)を generic_case_all 完成後に縮退 - 縮退計画詳細: `docs/private/roadmap2/phases/phase-30-final-joinir-world/TASKS.md` F-4.4 に記録済み diff --git a/docs/private b/docs/private index 57034f6a..6eee62b6 160000 --- a/docs/private +++ b/docs/private @@ -1 +1 @@ -Subproject commit 57034f6a9fb2614e9acb7dd75f1d927a9b8d0c69 +Subproject commit 6eee62b646b262eefdf1ce6aa322065372d285dd diff --git a/src/mir/join_ir/lowering/generic_case_a.rs b/src/mir/join_ir/lowering/generic_case_a.rs index 6bebab0f..33546632 100644 --- a/src/mir/join_ir/lowering/generic_case_a.rs +++ b/src/mir/join_ir/lowering/generic_case_a.rs @@ -9,8 +9,6 @@ use std::collections::BTreeMap; use crate::mir::join_ir::lowering::loop_scope_shape::CaseAContext; -// Phase 30: LoopScopeShape は将来の _with_scope API 追加時に再インポート -// use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape; use crate::mir::join_ir::lowering::value_id_ranges; use crate::mir::join_ir::lowering::value_id_ranges::skip_ws as vid; use crate::mir::join_ir::lowering::value_id_ranges::stage1_using_resolver as stage1_vid; @@ -18,45 +16,7 @@ use crate::mir::join_ir::{ BinOpKind, CompareOp, ConstValue, JoinContId, JoinFuncId, JoinFunction, JoinInst, JoinModule, LoopExitShape, LoopHeaderShape, MirLikeInst, }; -use crate::mir::loop_form::LoopForm; -use crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox; -use crate::mir::phi_core::loop_var_classifier::LoopVarClassBox; -use crate::mir::{MirFunction, MirQuery, ValueId}; - -/// v1: minimal_ssa_skip_ws 専用の汎用 Case A ロワー -/// -/// - LoopForm / VarClass / ExitLiveness は形の検証にのみ使う(パターンが合わなければ None) -/// - JoinModule の形は hand-written skip_ws と同一になるように組み立てる -pub fn lower_case_a_loop_to_joinir_for_minimal_skip_ws( - loop_form: &LoopForm, - var_classes: &LoopVarClassBox, - exit_live: &LoopExitLivenessBox, - query: &impl MirQuery, - mir_func: &MirFunction, -) -> Option { - // 追加の latch チェック(skip_ws 固有) - if loop_form.latch != loop_form.body && loop_form.latch != loop_form.header { - eprintln!( - "[joinir/generic_case_a] unexpected latch {:?} (body={:?}, header={:?}), fallback", - loop_form.latch, loop_form.body, loop_form.header - ); - return None; - } - - // CaseAContext で共通ロジックを実行 - let ctx = CaseAContext::new( - loop_form, - var_classes, - exit_live, - query, - mir_func, - "skip_ws", - |offset| vid::loop_step(offset), - )?; - - // コア実装に委譲(Phase 30: _with_scope と共通化) - lower_case_a_skip_ws_core(&ctx) -} +use crate::mir::ValueId; /// Phase 30: LoopScopeShape を直接受け取る skip_ws lowerer /// @@ -267,28 +227,24 @@ fn lower_case_a_skip_ws_core(ctx: &CaseAContext) -> Option { Some(join_module) } -/// Placeholder: trim minimal 用の generic Case A ロワー(v0, 未実装) +/// Phase 30 F-3.0.3: LoopScopeShape を直接受け取る trim lowerer /// -/// - いまは構造チェックのみで必ず None を返し、呼び元でフォールバックさせる -/// - 将来 trim_minimal を generic_case_a で置き換える際の導線として用意 -pub fn lower_case_a_loop_to_joinir_for_trim_minimal( - loop_form: &LoopForm, - var_classes: &LoopVarClassBox, - exit_live: &LoopExitLivenessBox, - query: &impl MirQuery, - mir_func: &MirFunction, +/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。 +/// CaseAContext::from_scope() 経由で ctx を作成。 +pub(crate) fn lower_case_a_trim_with_scope( + scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape, ) -> Option { - // CaseAContext で共通ロジックを実行 - let ctx = CaseAContext::new( - loop_form, - var_classes, - exit_live, - query, - mir_func, - "trim", - |offset| value_id_ranges::funcscanner_trim::loop_step(offset), - )?; + let ctx = CaseAContext::from_scope(scope, "trim", |offset| { + value_id_ranges::funcscanner_trim::loop_step(offset) + })?; + lower_case_a_trim_core(&ctx) +} +/// trim JoinModule 構築のコア実装 +/// +/// CaseAContext から JoinModule を構築する共通ロジック。 +/// `_for_trim_minimal` と `_with_scope` の両方から呼ばれる。 +fn lower_case_a_trim_core(ctx: &CaseAContext) -> Option { let string_key = ctx.pinned_name_or_first(0)?; let base_key = ctx.pinned_name_or_first(1).unwrap_or_else(|| string_key.clone()); let carrier_key = ctx.carrier_name_or_first(0)?; @@ -747,28 +703,24 @@ pub fn lower_case_a_loop_to_joinir_for_trim_minimal( Some(join_module) } -/// append_defs_minimal 用の generic Case A ロワー(LoopForm/VarClass/ExitLiveness ベース) +/// Phase 30 F-3.0.4: LoopScopeShape を直接受け取る append_defs lowerer /// -/// - LoopForm が単一 header/latch でない場合や、必要な変数がマッピングできない場合は None を返す。 -/// - 既存の手書き JoinIR(append_defs_entry + loop_step)と同じ形を目指す。 -pub fn lower_case_a_loop_to_joinir_for_append_defs_minimal( - loop_form: &LoopForm, - var_classes: &LoopVarClassBox, - exit_live: &LoopExitLivenessBox, - query: &impl MirQuery, - mir_func: &MirFunction, +/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。 +/// CaseAContext::from_scope() 経由で ctx を作成。 +pub(crate) fn lower_case_a_append_defs_with_scope( + scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape, ) -> Option { - // CaseAContext で共通ロジックを実行 - let ctx = CaseAContext::new( - loop_form, - var_classes, - exit_live, - query, - mir_func, - "append_defs", - |offset| value_id_ranges::funcscanner_append_defs::loop_step(offset), - )?; + let ctx = CaseAContext::from_scope(scope, "append_defs", |offset| { + value_id_ranges::funcscanner_append_defs::loop_step(offset) + })?; + lower_case_a_append_defs_core(&ctx) +} +/// append_defs JoinModule 構築のコア実装 +/// +/// CaseAContext から JoinModule を構築する共通ロジック。 +/// `_for_append_defs_minimal` と `_with_scope` の両方から呼ばれる。 +fn lower_case_a_append_defs_core(ctx: &CaseAContext) -> Option { let dst_key = ctx.pinned_name_or_first(0)?; let defs_key = ctx.pinned_name_or_first(1).unwrap_or_else(|| dst_key.clone()); let n_key = ctx.pinned_name_or_first(2).unwrap_or_else(|| defs_key.clone()); @@ -904,25 +856,23 @@ pub fn lower_case_a_loop_to_joinir_for_append_defs_minimal( Some(join_module) } -/// Stage1UsingResolver minimal 用の generic Case A ロワー(LoopForm/VarClass/ExitLiveness ベース) -pub fn lower_case_a_loop_to_joinir_for_stage1_usingresolver_minimal( - loop_form: &LoopForm, - var_classes: &LoopVarClassBox, - exit_live: &LoopExitLivenessBox, - query: &impl MirQuery, - mir_func: &MirFunction, +/// Phase 30 F-3.0.5: LoopScopeShape を直接受け取る Stage-1 UsingResolver lowerer +/// +/// 呼び出し元で LoopScopeShape を明示的に構築し、この関数に渡す。 +/// CaseAContext::from_scope() 経由で ctx を作成。 +pub(crate) fn lower_case_a_stage1_usingresolver_with_scope( + scope: crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape, ) -> Option { - // CaseAContext で共通ロジックを実行 - let ctx = CaseAContext::new( - loop_form, - var_classes, - exit_live, - query, - mir_func, - "stage1", - |offset| stage1_vid::loop_step(offset), - )?; + let ctx = + CaseAContext::from_scope(scope, "stage1", |offset| stage1_vid::loop_step(offset))?; + lower_case_a_stage1_usingresolver_core(&ctx) +} +/// Stage-1 UsingResolver JoinModule 構築のコア実装 +/// +/// CaseAContext から JoinModule を構築する共通ロジック。 +/// `_for_stage1_usingresolver_minimal` と `_with_scope` の両方から呼ばれる。 +fn lower_case_a_stage1_usingresolver_core(ctx: &CaseAContext) -> Option { let entries_key = ctx.pinned_name_or_first(0)?; let n_key = ctx.pinned_name_or_first(1).unwrap_or_else(|| entries_key.clone()); let modules_key = ctx.pinned_name_or_first(2).unwrap_or_else(|| entries_key.clone()); diff --git a/src/mir/join_ir/lowering/loop_scope_shape.rs b/src/mir/join_ir/lowering/loop_scope_shape.rs index 430e8853..5f518fe8 100644 --- a/src/mir/join_ir/lowering/loop_scope_shape.rs +++ b/src/mir/join_ir/lowering/loop_scope_shape.rs @@ -36,11 +36,11 @@ use std::collections::{BTreeMap, BTreeSet}; use crate::mir::join_ir::lowering::exit_args_resolver::resolve_exit_args; -use crate::mir::join_ir::lowering::loop_form_intake::{intake_loop_form, LoopFormIntake}; +use crate::mir::join_ir::lowering::loop_form_intake::LoopFormIntake; use crate::mir::loop_form::LoopForm; use crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox; use crate::mir::phi_core::loop_var_classifier::{LoopVarClass, LoopVarClassBox}; -use crate::mir::{BasicBlockId, MirFunction, MirQuery, ValueId}; +use crate::mir::{BasicBlockId, MirQuery, ValueId}; /// ループ変数スコープの統合ビュー /// @@ -95,7 +95,13 @@ use crate::mir::{BasicBlockId, MirFunction, MirQuery, ValueId}; /// - `body_locals`: ループ内だけで完結する変数(JoinIR では参照しない) /// - `exit_live`: ループ後に使われる変数(needs_exit_phi() == true) /// - `progress_carrier`: ループを前に進める変数(将来の Verifier 用) +/// +/// # Phase 30 Note +/// +/// Block ID フィールド (header/body/latch/exit) と progress_carrier は +/// F-3/F-4 で使用予定。現在は SSOT として保持。 #[derive(Debug, Clone)] +#[allow(dead_code)] // Phase 30: block IDs and progress_carrier are for future F-3/F-4 use pub(crate) struct LoopScopeShape { // === Block IDs (Phase 30: from LoopForm) === @@ -261,6 +267,7 @@ impl LoopScopeShape { } /// Check if a variable needs header PHI + #[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering pub fn needs_header_phi(&self, var_name: &str) -> bool { self.pinned.contains(var_name) || self.carriers.contains(var_name) } @@ -281,6 +288,7 @@ impl LoopScopeShape { } /// Get all variables that need header PHI (pinned + carriers) + #[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering pub fn header_phi_vars(&self) -> Vec { let mut result: Vec = self.pinned.iter().cloned().collect(); result.extend(self.carriers.iter().cloned()); @@ -288,6 +296,7 @@ impl LoopScopeShape { } /// Get all variables that need exit PHI + #[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering pub fn exit_phi_vars(&self) -> Vec { self.exit_live.iter().cloned().collect() } @@ -354,11 +363,8 @@ impl LoopScopeShape { /// # Usage /// /// ```ignore -/// let ctx = CaseAContext::new( -/// loop_form, var_classes, exit_live, query, mir_func, -/// "skip_ws", -/// |offset| vid::loop_step(offset), -/// )?; +/// let scope = LoopScopeShape::from_existing_boxes(...)?; +/// let ctx = CaseAContext::from_scope(scope, "skip_ws", |offset| vid::loop_step(offset))?; /// /// // ctx から必要な情報を取り出して JoinModule を構築 /// let header_shape = LoopHeaderShape::new_manual(ctx.pinned_ids.clone(), ctx.carrier_ids.clone()); @@ -387,93 +393,7 @@ pub(crate) struct CaseAContext { } impl CaseAContext { - /// CaseAContext を構築する - /// - /// # Arguments - /// - /// - `loop_form`: ループ構造情報 - /// - `var_classes`: 変数分類器 - /// - `exit_live`: exit liveness 情報 - /// - `query`: MIR クエリ - /// - `mir_func`: MIR 関数 - /// - `log_tag`: ログ出力用タグ(例: "skip_ws", "trim") - /// - `loop_step_id_fn`: offset から ValueId を生成する関数 - /// - /// # Returns - /// - /// Some(CaseAContext) if successful, None if validation fails or data is missing. - pub(crate) fn new( - loop_form: &LoopForm, - var_classes: &LoopVarClassBox, - exit_live: &LoopExitLivenessBox, - query: &impl MirQuery, - mir_func: &MirFunction, - log_tag: &str, - loop_step_id_fn: F, - ) -> Option - where - F: Fn(u32) -> ValueId, - { - // 1) LoopForm validation - if loop_form.header == loop_form.exit { - eprintln!( - "[joinir/generic_case_a/{}] loop_form malformed (header == exit), fallback", - log_tag - ); - return None; - } - - // 2) MIR から pinned/carrier/exit 情報を抽出 - let intake = intake_loop_form(loop_form, var_classes, query, mir_func)?; - - // 3) LoopScopeShape を構築 (Phase 30: includes block IDs) - let scope = LoopScopeShape::from_existing_boxes( - loop_form, - &intake, - var_classes, - exit_live, - query, - )?; - - let ordered_pinned = scope.pinned_ordered(); - let ordered_carriers = scope.carriers_ordered(); - - // 4) 変数名 → ValueId マッピングを構築 - let mut name_to_loop_id: BTreeMap = BTreeMap::new(); - let mut offset: u32 = 0; - for name in &ordered_pinned { - name_to_loop_id.insert(name.clone(), loop_step_id_fn(offset)); - offset += 1; - } - for name in &ordered_carriers { - name_to_loop_id.insert(name.clone(), loop_step_id_fn(offset)); - offset += 1; - } - - // 5) pinned_ids / carrier_ids を構築 - let pinned_ids: Vec = ordered_pinned - .iter() - .filter_map(|k| name_to_loop_id.get(k).copied()) - .collect(); - let carrier_ids: Vec = ordered_carriers - .iter() - .filter_map(|k| name_to_loop_id.get(k).copied()) - .collect(); - - // 6) exit_args を解決 - let exit_args = resolve_exit_args(&scope.exit_live, &name_to_loop_id, &ordered_carriers)?; - - Some(Self { - ordered_pinned, - ordered_carriers, - name_to_loop_id, - pinned_ids, - carrier_ids, - exit_args, - }) - } - - /// Phase 30: LoopScopeShape を直接受け取る新コンストラクタ + /// LoopScopeShape を直接受け取るコンストラクタ (Phase 30) /// /// # Arguments /// diff --git a/src/mir/join_ir/lowering/mod.rs b/src/mir/join_ir/lowering/mod.rs index 97e5753a..d9232970 100644 --- a/src/mir/join_ir/lowering/mod.rs +++ b/src/mir/join_ir/lowering/mod.rs @@ -30,7 +30,7 @@ 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; -pub use generic_case_a::lower_case_a_loop_to_joinir_for_minimal_skip_ws; +// 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;