メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

#79287accepted

go/types: add String methods to TypeParamList, TypeList, and Instance

ステータス変更: likely_accept accepted

要約

AIによる要約であり、誤りを含む場合があります。

概要

go/types パッケージの TypeParamListTypeListInstance という3つの型に String() メソッドを追加するproposalです。現状これらの型はデバッグ時に log.Println などに渡すと内部スライスのポインタがhex表記で出力されてしまうため、開発者が型情報を確認しにくい問題を解消します。

ステータス変更

likely_acceptaccepted
2026年5月13日にaclements氏がProposal Reviewとして「likely accept」と判定し、その後1週間以内に反論が上がらなかったため、2026年5月21日に正式に「accepted」となりました。設計変更の影響が小さく(既存の要素型が持つ String() を呼び出すだけ)、利便性向上が明確であることが判断の背景にあります。

技術的背景

現状の問題点

go/types パッケージはジェネリクス(型パラメータ)を扱うために TypeParamListTypeListInstance という型を提供していますが、これらには fmt.Stringer インターフェース(String() string)が実装されていません。そのため、デバッグ目的で log.Printlnfmt.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グループが判断した。
  • 対称性の確保: TypeListTypeParamList は対称的な設計になっているべきであり、一方にだけ String() があるのは不自然という観点が議論で共有された。
  • 反対意見なし: likely_accept から accepted への移行は1週間未満で完了しており、コミュニティから特段の反対意見は上がらなかった。

関連リンク