#81822active
spec: ignore channel direction during loose unification
新規提案
要約
AIによる要約であり、誤りを含む場合があります。
概要
chan E | chan<- E | <-chan E のように、向き(送信専用・受信専用・双方向)の違うチャネル型をまとめた制約では、現在は要素型 E を型推論できません。この proposal は、型推論の「loose unification(緩い単一化)」でチャネルの向きを無視するよう言語仕様を変え、こうした場合にも E を推論できるようにするものです。
ステータス変更
(新規) → active
2026年10月29日、@aclements が proposal review group を代表して、この proposal を active 列に追加しました。今後は週次の proposal review meeting で議論されます。提案者 @mcy は実装 CL(CL 829606)を既に用意しており、仕様変更が承認され次第取り込める状態です。もとになったバグ報告 #69153 は 2024 年から未解決で、Go 1.24、1.25 とマイルストーンが先送りされてきました。仕様を変える必要があるため、proposal として正式に審議することになったと考えられます。
技術的背景
現状の問題点
現在の仕様では、制約 C の型集合が「要素型が同じで、向きが矛盾しない」チャネル型だけで構成されている場合に限り、そのうち最も制限の強いチャネル型と実引数の型を loose unification します。
chan T | <-chan Tは推論できる(最も制限が強い<-chan Tを使う)chan T | <-chan T | chan<- Tは推論できない(<-chanとchan<-が矛盾し、共通の型を選べない)
この制限は、ジェネリクスの初期設計にあった「core type(型集合に共通する唯一の基底型)」という概念の名残です。core type は Go 1.25 で仕様から取り除かれました(#70128)。#69153 で @griesemer も、原因は「制約に core type がないこと」だと説明しています。
提案された解決策
CL 829606 では、仕様の Type unification の節を次のように変更します。
- 制約に由来する型方程式の条件を緩める。「要素型が同じで向きが矛盾しない」を「要素型が同じ」に変え、「最も制限の強いチャネル型」を「型集合内の任意のチャネル型」に変える。
- loose unification の規則に「両方がチャネル型なら、要素型を unify し、チャネルの向きは無視する」を追加する。
コンパイラ側の変更は小さく、types2とgo/typesのinfer.go・under.goに関数を 1 つ追加する程度です。CL の説明によれば、チャネル型だけで制約された型パラメータについて、推論のためだけに型集合内のチャネル型のどれか 1 つを代わりに使います。リリースノートの草案(doc/next/2-language.md)も CL に含まれています。
これによって何ができるようになるか
チャネルの向きを問わずに受け取る汎用ヘルパーを、呼び出し側で型引数を書かずに使えるようになります。
closeを呼ぶ汎用のClose関数len/capでバッファの埋まり具合を監視するユーティリティ(#69153 の元の用途)- 送信専用・受信専用・双方向のチャネルが混在するコードベースでの、メトリクス収集やデバッグ用ヘルパー
コード例
type anyChan[T any] interface {
chan T | <-chan T | chan<- T
}
func printCap[T any, C anyChan[T]](ch C) {
fmt.Println(cap(ch))
}
// Before: 要素型を毎回明示する必要がある
var send chan<- string = make(chan string)
printCap(send) // error: cannot infer T
printCap[string](send) // OK(ワークアラウンド)
// After: 向きに関係なく T が推論される
printCap(send) // T = string
printCap(make(<-chan int)) // T = int
printCap(make(chan any)) // T = any
議論のハイライト
- issue のコメントは、提案者の cc、gabyhelp による関連 issue の一覧、active 化の告知だけで、技術的な議論はまだ始まっていません。
- #69153 では @ianlancetaylor が「チャネル型には特別な型推論ルールが必要になるだろう」と述べ、@griesemer は原因が core type の欠如にあると説明しています。今回の提案はこの見立てに沿った最小限の変更です。
- 提案者によれば後方互換性は完全に保たれます。既存のプログラムの動作は変わらず、これまでコンパイルエラーだったプログラムが新たに通るようになるだけです。
- 性能面のコストは、推論アルゴリズムで制約ごとに型アサーションが 1 回増える程度とされています。
- 関連する未解決の issue に #65202 があります。
~<-chan E制約に双方向のchan intを渡すと、制約を満たさないというエラーになる問題です。ただし、これは推論ではなく「制約を満たすか」の判定の問題で、今回の提案の対象外と考えられます。
関連リンク
- Proposal Issue github.com/golang/go
- Review Comment proposal review meeting
- #65202: type inference limitation for directed channel type constraint
- #45920: make constraint type inference more flexible for some channel types
- #73527: proposal: spec: infer types from sufficiently constrained constraints
- Proposal Issue #81822
- Review Minutes
- #69153: cmd/compile: type parameter involving constraint with channels seems like it should be inferrable