# 通知設計書 106-hintConditionAlwaysFalse

## 概要

本ドキュメントは、Nimコンパイラの`hintConditionAlwaysFalse`ヒント通知に関する設計を定義する。このヒントは、条件式が常にfalseと評価される場合に通知するものである。

### 本通知の処理概要

`hintConditionAlwaysFalse`ヒントは、Nimコンパイラの意味解析フェーズで、`of`演算子（型チェック）による条件式がコンパイル時に常にfalseと判定された場合に出力される通知である。

**業務上の目的・背景**：Nimの`of`演算子はオブジェクト型の継承関係をチェックする。コンパイル時にこの条件が常にfalseと判定できる場合、それはコードのロジックエラーや到達不能なコードパスを示唆している可能性がある。この通知により、開発者は潜在的なバグや不必要なコードを発見し、コードの品質向上を図ることができる。

**通知の送信タイミング**：セマンティック解析フェーズで`of`演算子が処理される際、継承関係の差分計算（inheritanceDiff）の結果がhigh(int)（互換性なし）であるが、共通のスーパークラスが存在する場合に送信される。共通スーパークラスがない場合はエラーとなる。

**通知の受信者**：コンパイル実行者（開発者）がコンソール出力（stderr）を通じてこの通知を受信する。

**通知内容の概要**：「condition is always false: '$1'」という形式で、$1に条件式のレンダリング結果が代入される。

**期待されるアクション**：開発者はこの通知を確認し、当該条件式のロジックが正しいか検討する。意図しない場合は型設計やコードロジックを見直す。到達不能なコードパスは削除を検討する。

## 通知種別

コンソール出力（コンパイラヒント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（コンパイルプロセス内で即時出力） |
| 優先度 | 低（ヒント情報） |
| リトライ | 無し |

### 送信先決定ロジック

標準エラー出力（stderr）に送信される。`--stdout`オプションが指定されている場合は標準出力（stdout）に送信される。`writelnHook`が設定されている場合は、そのフック関数に委譲される。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| メッセージ種別 | Hint |
| フォーマット | `Hint: condition is always false: '{条件式}' [CondFalse]` |
| 色 | 緑色（HintColor = fgGreen） |

### 本文テンプレート

```
Hint: condition is always false: 'x of UnrelatedType' [CondFalse]
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $1 | 条件式 | renderTree(n)の結果 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| セマンティック解析 | of演算子処理 | `inheritanceDiff == high(int)` かつ `commonSuperclass != nil` | 継承関係がないが共通スーパークラスがある場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| optHints not in conf.options | ヒント出力自体が無効化されている場合 |
| hintConditionAlwaysFalse not in conf.notes | 個別にヒントが無効化されている場合 |
| commonSuperclass == nil | 共通スーパークラスがない場合はエラーになる |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[semmagic: of演算子処理] --> B[引数の型解析]
    B --> C[skipTypes処理]
    C --> D{両方ともオブジェクト型?}
    D -->|No| E[localError出力]
    D -->|Yes| F[inheritanceDiff計算]
    F --> G{diff == high int?}
    G -->|No| H[他の処理へ]
    G -->|Yes| I[commonSuperclass確認]
    I --> J{共通スーパークラスあり?}
    J -->|No| K[localError: この型にはなれない]
    J -->|Yes| L[message hintConditionAlwaysFalse]
    L --> M[結果をfalse(0)に最適化]
```

## データベース参照・更新仕様

該当なし（ファイルシステムやデータベースへのアクセスなし）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | このヒントは情報出力のみ | - |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | 条件が検出されるたびに出力 |

### 配信時間帯

制限なし（コンパイル実行時に即時出力）

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

- 条件式の内容がログに出力されるが、通常は型名程度であり機密性は低い

## 備考

- この最適化により、ランタイムでの不要な型チェックが除去される
- 対応する`hintConditionAlwaysTrue`（No.105）と対をなす
- 共通スーパークラスがない場合はヒントではなくエラー（localError）となる
- エラーメッセージ: 「'$1' cannot be of this subtype」

---

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

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

### 推奨読解順序

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

通知種別の定義と継承関係チェックの仕組みを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lineinfos.nim | `compiler/lineinfos.nim` | TMsgKind列挙型でhintConditionAlwaysFalseの定義を確認（110行目） |
| 1-2 | lineinfos.nim | `compiler/lineinfos.nim` | MsgKindToStr配列でメッセージ文字列を確認（229行目） |

**読解のコツ**: hintConditionAlwaysFalseは"CondFalse"という短縮名を持ち、出力時には[CondFalse]として表示される。

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

of演算子処理の起点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | semmagic.nim | `compiler/semmagic.nim` | of演算子のセマンティック処理（407-415行目）でhintConditionAlwaysFalse出力処理を確認 |

**主要処理フロー**:
1. **407行目**: `diff == high(int)`のチェック
2. **408行目**: `commonSuperclass(a, b) == nil`のチェック
3. **409行目**: 共通スーパークラスがない場合はlocalError
4. **411行目**: 共通スーパークラスがある場合、hintConditionAlwaysFalseを出力
5. **412-414行目**: 結果を0（false）に最適化

#### Step 3: 継承関係計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | types.nim | `compiler/types.nim` | inheritanceDiff関数とcommonSuperclass関数で継承階層の判定を理解 |

**主要処理フロー**:
- high(int)は互換性なしを意味し、さらにcommonSuperclassで共通祖先の有無を判定

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

```
semExpr (意味解析エントリ)
    │
    └─ semOf / semMagic (semmagic.nim)
           │
           ├─ semExprWithType: 左辺の式を解析
           │
           ├─ semExprWithType: 右辺の式を解析
           │
           ├─ skipTypes: 型のポインタを除去
           │
           ├─ inheritanceDiff(a, b): 継承関係を計算
           │
           └─ diff == high(int) の場合
                  │
                  ├─ commonSuperclass(a, b): 共通スーパークラス確認
                  │
                  ├─ nil の場合: localError
                  │
                  └─ 非nil の場合
                         │
                         ├─ message(hintConditionAlwaysFalse) ← ここで出力
                         │      └─ liMessage → styledMsgWriteln
                         │
                         └─ newIntNode(nkIntLit, 0): falseに最適化
```

### データフロー図

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

of演算子式       ───▶ semExprWithType      ───▶ 型情報取得
(x of T)               │
                       ▼
                  skipTypes              ───▶ ポインタ除去後の型
                       │
                       ▼
                  inheritanceDiff        ───▶ 差分値 = high(int)
                       │
                       ▼
                  commonSuperclass       ───▶ 共通スーパークラス有無
                       │
                       ▼
共通祖先あり     ───▶ message            ───▶ stderr/stdout
                       │                      "Hint: condition is always false..."
                       ▼
                  newIntNode(0)          ───▶ 最適化されたAST (false)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lineinfos.nim | `compiler/lineinfos.nim` | ソース | メッセージ種別定義（TMsgKind列挙型） |
| semmagic.nim | `compiler/semmagic.nim` | ソース | of演算子のセマンティック処理、hintConditionAlwaysFalse出力 |
| types.nim | `compiler/types.nim` | ソース | inheritanceDiff, commonSuperclass関数（継承関係計算） |
| msgs.nim | `compiler/msgs.nim` | ソース | メッセージ出力処理 |
| renderer.nim | `compiler/renderer.nim` | ソース | renderTree関数（条件式の文字列化） |
