# 機能設計書 14-オーバーロード解決

## 概要

本ドキュメントは、Nimコンパイラにおけるオーバーロード解決機能の設計仕様を記述する。この機能は同名の複数の関数（プロシージャ、演算子等）から、呼び出し時の引数に最も適合する候補を選択する機能である。

### 本機能の処理概要

オーバーロード解決機能は、関数呼び出し時に同名の複数の候補から、引数の型マッチングに基づいて最適な候補を選択するシグネチャマッチング機能である。

**業務上の目的・背景**：Nimは関数のオーバーロードをサポートしており、同名の関数を引数の型や数で区別して定義できる。これにより、プログラマは同じ概念的操作に対して統一されたインターフェースを提供できる。オーバーロード解決は、この言語機能を支える中核的なコンポーネントであり、呼び出しサイトでの引数型から最適な関数を選択する役割を担う。型安全性を維持しながら、直感的なAPI設計を可能にする。

**機能の利用シーン**：この機能はすべての関数呼び出し、メソッド呼び出し、演算子使用時に呼び出される。特に、ジェネリック関数の型パラメータ推論、暗黙の型変換を含むマッチング、ユーザー定義演算子の選択など、複雑な型推論を伴う場面で重要な役割を果たす。IDEのコード補完機能（nimsuggest）でも使用される。

**主要な処理内容**：
1. 候補関数の収集と初期化
2. 各候補に対するシグネチャマッチング
3. 型関係（等価、サブタイプ、変換可能等）の判定
4. ジェネリック型パラメータの推論と束縛
5. マッチスコアの計算と候補の比較
6. 最適な候補の選択またはあいまいエラーの報告

**関連システム・外部連携**：型システム（types.nim）と連携して型関係を判定する。セマンティック解析（sem*.nim）から呼び出され、選択された候補の情報を返す。Nimsuggestでは補完候補のランキングに使用される。

**権限による制御**：特になし。すべてのコードに適用される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | nimsuggest sug（補完） | 補助機能 | 補完候補のオーバーロード解決 |
| 1 | nimコンパイラメイン画面 | 補助機能 | 関数呼び出しの解決処理 |

## 機能種別

型マッチング / 関数選択 / 型推論

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ctx | PContext | Yes | セマンティック解析コンテキスト | nil不可 |
| callee | PSym or PType | Yes | 候補となる関数シンボルまたは型 | nil不可 |
| binding | PNode | No | 明示的なジェネリック引数 | nil可 |
| f, aOrig | PType | Yes | 仮引数型と実引数型 | nil可（nil安全） |
| flags | TTypeRelFlags | No | マッチングフラグ | 空集合可 |

### 入力データソース

- シンボルテーブルから収集された候補関数リスト
- 呼び出しサイトの引数AST
- コンパイラ設定（ConfigRef）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TCandidate | object | マッチング結果を保持する候補オブジェクト |
| TTypeRelation | enum | 型関係（isNone, isEqual, isSubtype等） |
| state | TCandidateState | 候補の状態（csEmpty, csMatch, csNoMatch） |
| bindings | LayeredIdTable | ジェネリック型パラメータの束縛 |

### 出力先

- 選択された候補情報として呼び出し元に返却
- エラー時は診断情報を蓄積

## 処理フロー

### 処理シーケンス

```
1. 候補の初期化
   └─ initCandidate()でTCandidateを作成
2. 明示的ジェネリック引数のマッチング
   └─ matchGenericParams()
3. 各引数の型マッチング
   └─ typeRel()を繰り返し呼び出し
4. マッチスコアの計算
   └─ exactMatches, subtypeMatches等を累積
5. 候補の比較
   └─ cmpCandidates()で最適候補を決定
6. 結果の返却
   └─ csMatch or csNoMatch
```

### フローチャート

```mermaid
flowchart TD
    A[オーバーロード解決開始] --> B[候補リスト収集]
    B --> C{候補あり?}
    C -->|No| D[エラー: 候補なし]
    C -->|Yes| E[各候補をループ]
    E --> F[initCandidate]
    F --> G{明示的型引数あり?}
    G -->|Yes| H[matchGenericParams]
    G -->|No| I[引数マッチング開始]
    H --> I
    I --> J[各引数についてtypeRel]
    J --> K{マッチ成功?}
    K -->|No| L[csNoMatch設定]
    K -->|Yes| M[スコア加算]
    M --> N{次の引数?}
    N -->|Yes| J
    N -->|No| O[候補リストに追加]
    L --> E
    O --> E
    E --> P{すべての候補処理完了?}
    P -->|No| E
    P -->|Yes| Q[cmpCandidatesで比較]
    Q --> R{一意な最適候補?}
    R -->|Yes| S[選択された候補を返却]
    R -->|No| T[あいまいエラー]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-14-01 | 完全一致優先 | exactMatchesが多い候補を優先 | スコア比較時 |
| BR-14-02 | サブタイプ優先 | 変換よりサブタイプ関係を優先 | 同スコア時 |
| BR-14-03 | 具体型優先 | ジェネリックより具体的な型を優先 | sumGenericで判定 |
| BR-14-04 | スコープ優先 | 内側のスコープで定義された候補を優先 | calleeScope比較 |
| BR-14-05 | あいまい禁止 | 同等の候補が複数ある場合はエラー | 比較結果が0 |

### 計算ロジック

- マッチスコア: exactMatches > genericMatches > subtypeMatches > intConvMatches > convMatches の順で重み付け
- ジェネリック度: `sumGeneric(t)` - 型のジェネリック度を数値化
- 候補比較: `cmpCandidates(a, b)` - 正/負/0を返却（正=aが良い、負=bが良い、0=同等）

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| kTypeMismatch | マッチエラー | 引数型が仮引数型と不一致 | MismatchInfoに詳細を記録 |
| kMissingParam | マッチエラー | 必須引数が不足 | エラーメッセージ生成 |
| kExtraArg | マッチエラー | 余分な引数が存在 | エラーメッセージ生成 |
| ambiguous | 解決エラー | 同等の候補が複数存在 | すべての候補を表示 |

### リトライ仕様

オーバーロード解決にリトライ機構はない。診断モード有効時は、すべての候補について詳細な不一致情報を収集する。

## トランザクション仕様

- ジェネリック型パラメータの束縛（bindings）は候補ごとに独立
- マッチング失敗時は束縛をロールバック（次の候補に影響なし）

## パフォーマンス要件

- 候補数に対してO(n)でマッチング
- 型比較は循環検出により無限ループを防止
- LayeredIdTableにより効率的な型束縛の管理

## セキュリティ考慮事項

- 特になし（コンパイル時処理）

## 備考

- TTypeRelationの順序は型システム（types.nim）と共有
- 診断モード（diagnosticsEnabled）で詳細情報を収集
- nimsuggestではpreferIters/preferRoutinesで候補をソート

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、マッチング結果を保持するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sigmatch.nim | `compiler/sigmatch.nim` | TCandidate型（47-91行目）: マッチング結果を保持するオブジェクト |
| 1-2 | sigmatch.nim | `compiler/sigmatch.nim` | MismatchKind列挙型（25-28行目）: 不一致の種類 |
| 1-3 | sigmatch.nim | `compiler/sigmatch.nim` | TCandidateState列挙型（36-37行目）: 候補の状態 |
| 1-4 | sigmatch.nim | `compiler/sigmatch.nim` | TTypeRelFlags（93-100行目）: マッチングフラグ |

**読解のコツ**: TCandidate.exactMatches, subtypeMatches等のフィールドがマッチスコアを表す。これらの値を比較して最適な候補を選択する。

#### Step 2: 候補の初期化を理解する

候補オブジェクトの初期化処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sigmatch.nim | `compiler/sigmatch.nim` | initCandidateAux()関数（110-117行目）: 基本的な初期化 |
| 2-2 | sigmatch.nim | `compiler/sigmatch.nim` | initCandidate()関数（119-122行, 243-270行）: シンボルありの初期化 |
| 2-3 | sigmatch.nim | `compiler/sigmatch.nim` | matchGenericParams()関数（173-218行）: 明示的型引数のマッチング |

**主要処理フロー**:
- **112-116行**: TCandidate構造体の初期化
- **256-270行**: 明示的型引数がある場合のマッチング処理

#### Step 3: 型関係判定を理解する

型マッチングの中心的な関数。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sigmatch.nim | `compiler/sigmatch.nim` | typeRel()関数（138-139行目）: 型関係判定のエントリーポイント |
| 3-2 | sigmatch.nim | `compiler/sigmatch.nim` | put()関数（124-136行目）: ジェネリック型パラメータの束縛 |

#### Step 4: 候補比較を理解する

複数の候補を比較して最適なものを選択。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sigmatch.nim | `compiler/sigmatch.nim` | checkGeneric()関数（293-309行目）: ジェネリック候補の比較 |
| 4-2 | sigmatch.nim | `compiler/sigmatch.nim` | sumGeneric()関数（311-368行目）: ジェネリック度の計算 |
| 4-3 | sigmatch.nim | `compiler/sigmatch.nim` | complexDisambiguation()関数（370-392行目）: 複雑な候補の比較 |
| 4-4 | sigmatch.nim | `compiler/sigmatch.nim` | writeMatches()関数（394-400行目）: デバッグ用マッチ情報出力 |

**主要処理フロー**:
- **311-368行**: 型の「ジェネリック度」を数値化（具体的な型ほど高スコア）
- **370-387行**: すべての引数でより具体的な候補を判定

#### Step 5: ジェネリックパラメータマッチングを理解する

明示的なジェネリック引数のマッチング。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | sigmatch.nim | `compiler/sigmatch.nim` | matchGenericParam()関数（141-171行目）: 単一のジェネリックパラメータをマッチ |
| 5-2 | sigmatch.nim | `compiler/sigmatch.nim` | matchGenericParams()関数（173-218行目）: 全パラメータのマッチング |

### プログラム呼び出し階層図

```
オーバーロード解決
    │
    ├─ initCandidate()
    │      └─ matchGenericParams() [明示的型引数がある場合]
    │             └─ matchGenericParam()
    │                    └─ typeRel()
    │
    ├─ typeRel() [引数ごとにマッチング]
    │      └─ put() [型パラメータ束縛]
    │
    └─ cmpCandidates() [候補比較]
           ├─ checkGeneric()
           │      └─ typeRel()
           ├─ sumGeneric()
           └─ complexDisambiguation()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

候補リスト ──────────────▶ 各候補について
                               │
                               ▼
                      initCandidate()
                               │
                               ▼
実引数リスト ────────────▶ typeRel() [引数ごと]
                               │
                    ┌──────────┼──────────┐
                    ▼          ▼          ▼
               exactMatch  subtype   convert
                    │          │          │
                    └──────────┼──────────┘
                               ▼
                      スコア加算
                               │
                               ▼
                      cmpCandidates() ─────────▶ 最適候補 or エラー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sigmatch.nim | `compiler/sigmatch.nim` | ソース | オーバーロード解決のメイン実装 |
| types.nim | `compiler/types.nim` | ソース | TTypeRelation、型比較関数 |
| semcall.nim | `compiler/semcall.nim` | ソース | 関数呼び出しのセマンティック解析 |
| semexprs.nim | `compiler/semexprs.nim` | ソース | 式のセマンティック解析 |
| layeredtable.nim | `compiler/layeredtable.nim` | ソース | LayeredIdTable実装（型束縛管理） |
| concepts.nim | `compiler/concepts.nim` | ソース | コンセプト（型クラス）のマッチング |
