#79603likely_accept
go/types: NewType{Param,}List
新規提案
要約
AIによる要約であり、誤りを含む場合があります。
概要
go/types パッケージに NewTypeParamList および NewTypeList の2つのコンストラクタ関数を追加するproposalです。これにより、型パラメータリスト(TypeParamList)と型リスト(TypeList)をプログラムから安全に生成できるようになります。
ステータス変更
(なし) → likely accept
Proposal Review GroupのAustin Clements(@aclements)が2026年5月28日にlikely acceptと判断しました。APIが非常にシンプルで、明確な動機(unsafeパッケージへの依存排除)があること、また@adonovanらコアチームメンバーがNewTypeListの追加にも同意したことが背景にあります。
技術的背景
現状の問題点
go/typesパッケージは型パラメータリスト(TypeParamList)と型リスト(TypeList)を公開していますが、これらを外部から構築するコンストラクタが存在しません。既存のTypeParamListを扱うツール側では、以下のような問題が発生しています。
- コンパイラ内部(noder): レシーバと関数の型パラメータを結合する際に、いったん
[]*TypeParamスライスに変換しなければならない。 go/ssa(x/tools):Function.TypeParamsが*TypeParamListを返すAPIを維持するために、unsafe.Pointerを用いた危険なキャストが必要になっている。
// 現在のワークアラウンド(go/ssaでの実装例)
func consTypeParamLists(l, r *types.TypeParamList) *types.TypeParamList {
tpars := make([]*types.TypeParam, l.Len()+r.Len())
for i := range l.Len() {
tpars[i] = l.At(i)
}
for i := range r.Len() {
tpars[i+l.Len()] = r.At(i)
}
// unsafe.Pointerによる強制キャスト(危険)
return (*types.TypeParamList)(unsafe.Pointer(&tpars))
}
提案された解決策
以下の2つのエクスポートされたコンストラクタ関数をgo/typesに追加します。
func NewTypeParamList(tparams ...*TypeParam) *TypeParamList
func NewTypeList(types ...*Type) *TypeList
実装は非常にシンプルで、内部フィールドに渡された引数をそのまま格納します。NewTypeListの追加は@adonovan(Googler)が提案し、対称性と一貫性の観点からproposalに組み込まれました。
これによって何ができるようになるか
ツール作者やコンパイラ実装者がTypeParamListおよびTypeListを安全・明示的に生成できるようになります。
コード例
// Before: unsafe.Pointerを使った強制キャスト(危険)
func mergeTypeParams(l, r *types.TypeParamList) *types.TypeParamList {
tpars := make([]*types.TypeParam, l.Len()+r.Len())
for i := range l.Len() {
tpars[i] = l.At(i)
}
for i := range r.Len() {
tpars[i+l.Len()] = r.At(i)
}
return (*types.TypeParamList)(unsafe.Pointer(&tpars)) // 内部レイアウトに依存
}
// After: 安全なコンストラクタを使った書き方
func mergeTypeParams(l, r *types.TypeParamList) *types.TypeParamList {
tpars := make([]*types.TypeParam, l.Len()+r.Len())
for i := range l.Len() {
tpars[i] = l.At(i)
}
for i := range r.Len() {
tpars[i+l.Len()] = r.At(i)
}
return types.NewTypeParamList(tpars...) // 安全・明示的
}
議論のハイライト
NewTypeListの追加: 元のproposalはNewTypeParamListのみを対象としていたが、@adonovanがNewTypeListも追加すべきと提案し、API設計の対称性から採用された。- 動機の明確さ:
unsafe.Pointerを使った実装がx/toolsのSSAパッケージで実際に行われており、標準ライブラリとしてAPIを提供すべき根拠が明確だった。 - Genericメソッド提案(#77273)との関連: Goにgenericメソッドが将来追加された場合、レシーバの型パラメータと関数の型パラメータを統合する操作はさらに頻繁になるため、本APIの必要性は増す。
- APIのシンプルさ: コンストラクタの実装は内部フィールドへの代入のみで、複雑なバリデーションや副作用がなく、リスクが非常に低い。
TypeParamListの不変性: 既存のbindTParamsは型パラメータにインデックスを割り当てる副作用があるが、NewTypeParamListはそのような副作用を持たない設計であることが期待される。
関連リンク
- Proposal Issue github.com/golang/go
- Review Comment proposal review meeting
- Proposal Issue #79603
- Review Minutes (issuecomment-4561007040)
- Proposal Review Meeting Minutes Issue #33502
- 関連Issue: go/types additions to support type parameters #47916
- 関連Issue: NewSignatureType mutates TypeParams #67293
- 関連Issue: spec: generic methods for Go #77273