# 機能設計書 99-ポスト推論チェック

## 概要

本ドキュメントは、F#コンパイラにおけるポスト推論チェック（Post Inference Checks）機能について記述する。型推論が完了した後のTAST（Typed Abstract Syntax Tree）に対して、追加のセマンティックチェックを実行する。

### 本機能の処理概要

**業務上の目的・背景**：型推論の完了後、TASTには完全な型情報が付与されている。この段階で、型推論中には検出できない制約違反やセマンティックエラーを検出する。byref型のエスケープチェック、未使用変数の警告、reraise使用の妥当性チェック等、型情報が確定してから初めて可能になる検証を行う。

**機能の利用シーン**：
- コンパイル時の最終検証フェーズ
- IDE連携での詳細な警告表示
- ランタイムエラーを防ぐための静的検証
- コード品質の向上

**主要な処理内容**：
1. byref/Span型のエスケープチェック - スタック参照の不正なエスケープ防止
2. 未使用変数のチェック - 未使用のlet束縛に対する警告
3. reraiseチェック - try/with外でのreraise使用の検出
4. 再帰参照のチェック - 不正な再帰参照の検出
5. 型パラメータ制約の最終検証

**関連システム・外部連携**：型チェッカー（CheckExpressions.fs）の後に実行され、TASTを入力として受け取る。結果は診断メッセージとして出力される。

**権限による制御**：該当なし（コンパイラ内部機能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | IDE統合 | 参照画面 | 未使用変数警告、エラー表示 |

## 機能種別

セマンティックチェック

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cenv | cenv | Yes | チェック環境 | - |
| env | env | Yes | 現在の環境 | - |
| expr | Expr | Yes | チェック対象の式 | - |

### 入力データソース

型チェッカーからのTAST（型付き抽象構文木）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | unit | チェック完了（警告/エラーは副作用として出力） |

### 出力先

コンパイラ診断出力

## 処理フロー

### 処理シーケンス

```
1. 式のトラバーサル
   ├─ 全ての部分式を再帰的に訪問
   └─ 各式に対してチェックを適用

2. byref/Spanチェック
   ├─ byref値のスコープ追跡
   ├─ Span型のスタック参照追跡
   └─ エスケープ検出時にエラー

3. 未使用変数チェック
   ├─ let束縛の使用状況追跡
   └─ 未使用時に警告

4. reraiseチェック
   ├─ try/withコンテキストの追跡
   └─ 不正なreraise使用の検出

5. 型検証
   ├─ byref-like型の使用制限
   └─ 型パラメータ制約の最終確認
```

### フローチャート

```mermaid
flowchart TD
    A[TAST入力] --> B[式トラバーサル]
    B --> C{式の種類}
    C -->|Let束縛| D[未使用チェック]
    C -->|Lambda| E[byrefエスケープチェック]
    C -->|Reraise| F[reraiseコンテキストチェック]
    C -->|その他| G[再帰的チェック]
    D --> G
    E --> G
    F --> G
    G --> H{全式処理済?}
    H -->|No| B
    H -->|Yes| I[チェック完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-1 | byrefエスケープ禁止 | byref値はラムダでキャプチャ不可 | 常時 |
| BR-99-2 | Spanエスケープ禁止 | スタック参照Spanは返却不可 | 常時 |
| BR-99-3 | reraiseスコープ | reraiseはwith句内でのみ使用可 | 常時 |
| BR-99-4 | 未使用警告 | _で始まらない未使用変数は警告 | 常時 |

### 計算ロジック

**Limitスコープ計算**：
```fsharp
type Limit = { scope: int; flags: LimitFlags }
// scope: 0 = グローバル、1以上 = ローカルスコープ
// flags: ByRef, SpanLike, StackReferringSpanLike等
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FS0406 | ByrefUsedInInvalidWay | byrefのエスケープ | byrefを使用しない設計に変更 |
| FS0407 | ByrefUsedInClosure | byrefをクロージャでキャプチャ | ローカル変数にコピー |
| FS1182 | UnusedValue | 未使用の変数 | 変数を使用するか_で始める |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

ポスト推論チェックのオーバーヘッドは全体のコンパイル時間の5%未満であること

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

該当なし

## 備考

`--warnaserror:1182`で未使用変数警告をエラーに昇格できる。byrefチェックはメモリ安全性に重要。

---

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

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

### 推奨読解順序

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

チェック環境とLimit型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PostInferenceChecks.fs | `src/Compiler/Checking/PostInferenceChecks.fs` | cenv型、env型、Limit型の定義 |

**主要な型定義**:
- **64-104行目**: env型 - チェック環境（boundTypars, argVals, returnScope等）
- **126-188行目**: Limit型 - byref/Spanのスコープ制限
- **190-227行目**: cenv型 - チェックコンテキスト

#### Step 2: エントリーポイントを理解する

ポスト推論チェックの主要な関数を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PostInferenceChecks.fs | `src/Compiler/Checking/PostInferenceChecks.fs` | CheckExpr, CheckEscapes関数 |

**主要処理フロー**:
- **231-236行目**: IsValArgument, IsValLocal - 変数の分類
- **238-295行目**: GetLimitVal, GetLimitValByRef - Limit計算
- **296-331行目**: BindVal - 変数バインディングと未使用チェック
- **475-500行目**: CheckEscapes - エスケープチェック

#### Step 3: 呼び出し元を理解する

ポスト推論チェックがどこから使われるかを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ParseAndCheckInputs.fs | `src/Compiler/Driver/ParseAndCheckInputs.fs` | ファイルチェック後の呼び出し |

**読解のコツ**:
- Limit型はbyref/Spanの「どこまでエスケープ可能か」を表す
- scopeが大きいほどローカル（エスケープ不可）
- CheckEscapesはラムダ境界でのbyrefキャプチャを検出

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

```
ParseAndCheckInputs.fs
    │
    └─ PostInferenceChecks.fs
           │
           ├─ env（チェック環境）
           │      ├─ boundTyparNames: 型パラメータ名
           │      ├─ boundTypars: 型パラメータ
           │      ├─ argVals: 関数引数
           │      └─ returnScope: 戻り値スコープ
           │
           ├─ Limit（スコープ制限）
           │      ├─ scope: スコープレベル
           │      └─ flags: ByRef / SpanLike / StackReferring
           │
           ├─ CheckExpr
           │      ├─ CheckTypeDeep: 型チェック
           │      ├─ CheckEscapes: エスケープチェック
           │      └─ BindVal: 変数バインディング
           │
           └─ 診断出力
                  ├─ FS0406: byrefエスケープ
                  ├─ FS0407: byrefクロージャキャプチャ
                  └─ FS1182: 未使用変数
```

### データフロー図

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

TAST ───▶ PostInferenceChecks ───▶ 診断メッセージ
          │
          ├─ 式トラバーサル
          │      └─ 全ノードを訪問
          │
          ├─ Limit計算
          │      ├─ byrefスコープ
          │      └─ Spanスコープ
          │
          └─ チェック実行
                 ├─ エスケープ検出
                 ├─ 未使用検出
                 └─ reraise検出
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PostInferenceChecks.fs | `src/Compiler/Checking/PostInferenceChecks.fs` | ソース | ポスト推論チェック実装 |
| PostInferenceChecks.fsi | `src/Compiler/Checking/PostInferenceChecks.fsi` | ソース | 公開シグネチャ |
| ParseAndCheckInputs.fs | `src/Compiler/Driver/ParseAndCheckInputs.fs` | ソース | 呼び出し元 |
| TypedTree.fs | `src/Compiler/TypedTree/TypedTree.fs` | ソース | TAST型定義 |
| TypedTreeOps.fs | `src/Compiler/TypedTree/TypedTreeOps.fs` | ソース | TAST操作関数 |
