#79427active
decouple export data formats used by compiler and x/tools
新規提案
要約
AIによる要約であり、誤りを含む場合があります。
概要
コンパイラ(cmd/compile)とツール群(x/tools)が共有するエクスポートデータのフォーマットを分離し、それぞれが独立して進化できるようにするproposalです。現在の密結合な構造を解消し、Go言語の新機能追加プロセスを簡素化することを目的としています。
ステータス変更
(新規) → active
2026年5月27日の週次Proposal Review Meeting(@adonovan, @bradfitz, @cherrymui, @griesemer, @ianlancetaylor, @neild, @rolandshoemaker 出席)にて、active列に追加され、週次レビューの対象となりました。@griesemerが「良いアイデアだが、ツール側への影響の把握が必要」とコメントしており、影響調査のための実験を提案しています。
技術的背景
現状の問題点
Goのエクスポートデータ(export data)とは、コンパイル時にパッケージ間で型情報を共有するためのバイナリ形式のシリアライズデータです。現在、2つの異なるフォーマットが存在します。
- unified形式(u形式): cmd/compileが読み書きする形式。インライン展開やジェネリクスに対応した現行フォーマット。
- indexed形式(i形式): x/tools(gopls等)が読み書きする旧来のフォーマット。
問題は、go list -exportコマンドがコンパイラを呼び出してエクスポートデータファイルを生成するため、x/toolsのリーダーがu形式も読めなければならない点にあります。この結果、コンパイラとx/toolsの間に複雑な依存関係が生じており、どちらかのフォーマットを変更すると両方のコードを更新しなければなりません。
特に、Go言語に新機能を追加する際の手順が複雑になっています。例えばジェネリクスやエイリアス型パラメータの追加時に、std(標準ライブラリ)とx/toolsの間での版ずれ(version skew)への対処が求められ、開発の難易度が上がっていました。
提案された解決策
提案者(@adonovan、@cherrymui のアイデア)は以下の分離策を提示しています。
コンパイラ側(cmd/compile):
- u形式のみを読み書きする
- 同一バージョンのツールチェーンでのみ読み書き可能とし、形式を内部実装の詳細として扱う
- 外部からの読み取りサポートを不要とし、自由に進化させる
ツール側(x/tools): - i形式のみを読み書きする
go list -exportが呼び出すバックエンドを、cmd/compileから新しい cmd/export ツールに切り替える- cmd/export は
go/ast + go/types + vendor/x/toolsを基盤とし、Goソースを解析・型検査してi形式のエクスポートデータを出力するシンプルなフロントエンドツール
cmd/exportは関数本体の型検査が不要なため(go/typesがそのモードをサポート済み)、実際のコンパイラより大幅に高速に動作すると見込まれています。
これによって何ができるようになるか
この分離により、Go言語の新機能追加プロセスが以下のように整理されます。
go/typesに対応を追加 → 単一パッケージのテストが可能に- コンパイラとそのエクスポートデータリーダー/ライターに対応を追加 → 複数パッケージのコンパイラテストが可能に
- x/toolsのリーダー/ライターに対応を追加
- x/toolsをGOROOTにvendoring →
go list -exportが新フォーマットを出力 - Goリリース
コンパイラとツールが独立したフォーマットを持つことで、コンパイラ側は毎日自由にフォーマットを変更でき、x/tools側はi形式のみに集中できます。
コード例
// Before: x/toolsのReaderがコンパイラのu形式も理解する必要がある
// go list -export はcmd/compileを実行し、u形式のエクスポートデータを生成
// gcexportdata.Read() はu形式・i形式の両方に対応しなければならない
pkg, err := gcexportdata.Read(exportFile, fset, imports, path)
// After: 分離後の構造
// go list -export は新しいcmd/exportツールを実行し、i形式のエクスポートデータを生成
// gcexportdata.Read() はi形式のみに対応すればよい
pkg, err := gcexportdata.Read(exportFile, fset, imports, path)
// APIは変わらないが、内部実装が簡素化される
議論のハイライト
- 影響調査の必要性: @griesemerは実験的にコンパイラのエクスポートデータを「毒入り(poison)」にして、ツール側で何が壊れるかを確認することを提案しています。go/importerパッケージが.aファイルを直接読む用途(
go list -json経由等)への影響が未知数であり、調査が必要とされています。 - 後方互換性について議論: 複数の関係者から「x/toolsのフォーマット後方互換性を保証できないか」という声があがりましたが、新言語機能が低レベルのパッケージに広く採用された場合、バージョンずれエラーを遅延させても実益が少ないと整理されています。
- gccgoサポートの終了: @adonovanはこの議論と関連して、ジェネリクスをサポートしないまま実質停止しているgccgoのサポートを廃止するproposal(#79453)を別途提出しました。
- 関連proposal #69491との連携: go/types自体にImport/Export関数を追加するproposal(#69491)と関連しており、これら一連の取り組みによってエクスポートデータの管理が整理される方向性にあります。
- cmd/exportツールの軽量性: 関数本体の型検査が不要なため、cmd/compileより大幅に高速になる見込みで、クリティカルパスも短くなるとされています。
関連リンク
- Proposal Issue github.com/golang/go
- Review Comment proposal review meeting
- 関連Issue #78856: proposal: x/tools/go/gcexportdata: add WriteShallow, ReadShallow
- Proposal Issue #79427
- Review Minutes
- 関連Issue #69491: go/types: add Import, Export functions
- 関連Issue #68898: x/tools/go/gcexportdata: Read to support only 2 Go releases + tip
- 関連Issue #79453: proposal: drop gccgo