go/types: add String methods to TypeParamList, TypeList, and Instance
要約
概要
go/types パッケージの TypeParamList、TypeList、Instance という3つの型に String() メソッドを追加するproposalです。現状これらの型はデバッグ時に log.Println などに渡すと内部スライスのポインタがhex表記で出力されてしまうため、開発者が型情報を確認しにくい問題を解消します。
ステータス変更
likely_accept → accepted
2026年5月13日にaclements氏がProposal Reviewとして「likely accept」と判定し、その後1週間以内に反論が上がらなかったため、2026年5月21日に正式に「accepted」となりました。設計変更の影響が小さく(既存の要素型が持つ String() を呼び出すだけ)、利便性向上が明確であることが判断の背景にあります。
技術的背景
現状の問題点
go/types パッケージはジェネリクス(型パラメータ)を扱うために TypeParamList・TypeList・Instance という型を提供していますが、これらには fmt.Stringer インターフェース(String() string)が実装されていません。そのため、デバッグ目的で log.Println や fmt.Printf("%v", ...) に渡すと、型の中身ではなくポインタのhex値が出力されてしまいます。
// 現状の問題: デバッグ時に不便な出力になる
named := types.NewNamed(...)
log.Println(named.TypeParams()) // &{0xc0001234...} のようなhex出力
なお、過去に TypeList.String() がデバッグ支援目的で一時的に追加された実績(CL 346552)がありましたが、正式なproposalを経ずに追加されたため後に削除(CL 381634、issue #50760)されました。今回のproposalはその反省を踏まえ、正式な手続きを経て3つの型すべてに String() を追加するものです。
提案された解決策
go/types パッケージの以下の3型に String() メソッドを追加します。
TypeParamList.String()— 各*TypeParam要素のString()を用いてリストを文字列化TypeList.String()— 各Type要素のString()を用いてリストを文字列化Instance.String()—TypeArgs(*TypeList)とTypeを用いてインスタンス情報を文字列化
実装はすでにgo/typesおよびcmd/compile/internal/types2の両パッケージに対して CL 780581 として提出されています。
これによって何ができるようになるか
型チェッカー・型解析ツール・リフレクション的なコード生成ツールを開発する際に、ジェネリック型のインスタンス化情報や型パラメータをデバッグ出力する際の可読性が大幅に向上します。
コード例
// Before: TypeParamList / TypeList / Instance をログ出力すると不親切な表示になる
import "go/types"
func debugTypes(fn *types.Func) {
sig := fn.Type().(*types.Signature)
tparams := sig.TypeParams()
// log.Println(tparams) → &{0xc000123400} のようなhex表記
for i := 0; i < tparams.Len(); i++ {
log.Println(tparams.At(i)) // 要素単体は String() があるので読める
}
}
// After: String() が実装され、直接渡してもわかりやすい出力が得られる
func debugTypes(fn *types.Func) {
sig := fn.Type().(*types.Signature)
tparams := sig.TypeParams()
log.Println(tparams) // [T constraints.Ordered, U any] のような可読出力
}
議論のハイライト
- 提案の動機:
log.Printlnなどに渡すとhex表示になり、ジェネリクス関連ツール開発時のデバッグが非常に困難になっている点が発端。 - 過去の経緯:
TypeList.String()は一度 Go 1.18 開発中に非公式に追加されたが、proposalプロセスを経ていないとして削除された(issue #50760)。今回はその再提案を含む。 - 設計方針: 新しいロジックは不要で、既存の要素型が持つ
String()メソッドを呼び出すだけで実装できるため、リスクが低いとReviewグループが判断した。 - 対称性の確保:
TypeListとTypeParamListは対称的な設計になっているべきであり、一方にだけString()があるのは不自然という観点が議論で共有された。 - 反対意見なし: likely_accept から accepted への移行は1週間未満で完了しており、コミュニティから特段の反対意見は上がらなかった。