# 関数オーバーロードと名前解決の仕組み

TLコンパイラにおける関数およびメソッドのオーバーロード解決（Overload Resolution）の仕組みについて解説します。
TL言語では、ランタイム（バックエンド）レベルでの関数名の衝突を避けるため、一意な名前（マングリング名）を用いた解決を行っています。

## 概要

オーバーロード解決は、複雑な候補探索（Candidate Lookup）ではなく、**決定的（Deterministic）な名前マングリング**によってシンプルに実現されています。

1.  **Name Mangling（名前マングリング）**: メソッド名と引数型から、一意の識別子を生成します。
2.  **TypeManager**: マングリングされた一意の名前をキーとして、関数のシグネチャを管理・照合します。

---

## 1. Name Mangling（名前マングリング）

TLのオーバーロード解決の核心は、「引数の型が異なれば、生成される関数名も異なる」というマングリング規則にあります。

マングリングのロジックは `src/compiler/codegen/builtin_types/resolver.rs` に実装されています。

### 命名規則

基本パターン: `tl_{type_name}_{arg1}_{arg2}_{method_name}`

*   **Prefix**: `tl_` (ランタイム関数であることを示す)
*   **Type Name**: レシーバの型名（小文字）。例: `tensor`, `vec`
*   **Method Name**: メソッド名。例: `new`, `push`
*   **Arg Types**: 引数の型に基づく識別子。

#### マングリングの例

| TLコード | 生成されるマングリング名 |
| :--- | :--- |
| `Vec<i64>::new()` | `tl_vec_i64_new` |
| `Vec<String>::new()` | `tl_vec_string_new` |
| `Tensor::zeros([2, 2])` | `tl_tensor_ptr_zeros` |

---

## 2. 解決プロセス (Resolution Flow)

`src/compiler/semantics.rs` におけるメソッド呼び出し（`StaticMethodCall` 等）の解決は、以下のシンプルなステップで行われます。

### ステップ 1: マングリング名の計算

呼び出し元のコードに記述された「型名」「メソッド名」および「引数の型」から、期待されるマングリング名を計算します。

```rust
// 例: Tensor::min(0) 呼び出し時 (引数は i64)
let mangled_name = resolve_static_method_name("Tensor", "min", &[Type::I64]);
// => "tl_tensor_i64_min"
```

### ステップ 2: TypeManager への照会

計算されたマングリング名をキーとして、`TypeManager` に**ジェネリックな関数定義**が存在するか問い合わせます。

*   **ヒットした場合**: そのジェネリック定義が呼び出すべきメソッドの雛形として特定されます。AST上のメソッド名をマングリング名に書き換え、型チェック（最終確認）を行います。
*   **ミスした場合**: そのシグネチャに一致するオーバーロードは存在しないと判断し、エラー（またはユーザー定義メソッドへのフォールバック）とします。

### 特徴

この方式では、同名のメソッドをリストで管理して適合度を計算するようなコストの高い処理を行わず、**O(1) のハッシュマップ検索**だけで解決が完了します。
したがって、`TypeManager` は「候補リスト」を持つ必要はありません。

---

## 実装における注意点

*   **厳密な型一致**: マングリングは型に厳密です。例えば `i32` を期待する関数に `i64` を渡した場合、マングリング名が一致せず（`..._i32_...` vs `..._i64_...`）、解決に失敗します。
*   **組み込み型の登録**: 新しい組み込み関数を追加する場合、その実装側（C/Rustランタイム）のシンボル名と、コンパイラが計算するマングリング名が完全に一致している必要があります。

このシンプルなアーキテクチャにより、コンパイラの複雑性を抑えつつ、型安全なオーバーロードを実現しています。
