タラバガニー設計局stalins.clubNOTE/notes/export-data-uir-v4

エクスポートデータ形式と UIR V4

エクスポートデータとは、Go のコンパイラがビルド済みパッケージの型情報を吐き出す形式で、他のパッケージをコンパイルするときや go/types 系のツールがパッケージを読み込むときに使われる。Go 1.27 のジェネリクスメソッドは、このエクスポートデータのバージョンを1つ上げることを要求した。

internal/pkgbits/version.go には次のコメントがある。

// V4: encodes generic methods as standalone function objects
V4

ジェネリクスメソッドを独立した関数オブジェクトとしてエンコードするために、V4 へのバンプが必要になったということである。

この手のバージョン変更は波及が大きい。古い x/tools を vendoring しているツールは、バージョンを認識できずに import そのものが失敗する。staticcheck が最初につまづいたのがこれで (dominikh/go-tools #1711, 2026-04-15)、当時はまだ V3 の話だったが症状は同じ形をしている。

internal error in importing "internal/byteorder"
(cannot decode "internal/byteorder", export data version 3 is greater than
maximum supported version 2); please report an issue (compile)

2026-08-15 時点でいちばん活発に動いているのは、この波及を根から解決しようという提案 #79427 "proposal: decouple export data formats used by compiler and x/tools" (2026-05-15 提出、2026-08-13 更新) である。コンパイラが使う unified (u) 形式と、x/tools が使う indexed (i) 形式を切り離し、go list -export をコンパイラ (cmd/compile) ではなく新設する cmd/export (go/ast + go/types ベースで、関数本体を型検査しない分速い) に流そう、という内容。aclements のコメントが提案の動機を端的に言い表している。

the main reason we ever change the export data is because we need to for new language features.

adonovan の 2026-07-23 の案は、i 形式・u 形式・コンパイラ私有の p 形式の3つに分け、まず p を u からわざとずらして何が壊れるか観察しよう、というもの。2026-08-15 時点で open のまま議論が続いている。

言語機能の追加そのものはコンパイラ側で完結しても、エクスポートデータのバージョン変更はエコシステム全体に波及する。この非対称性は linter が Go 1.27 に追いついていない で見る linter 対応の遅れとも地続きで、実装方式が GC shape stenciling と dictionary のようにコンパイラ内部で閉じていても、それを外から観測する側の仕組みまでは閉じない、という構造を示している。

出典

  • Go Release Party 1.27 の発表資料リポジトリ memo.md §2
  • Go Release Party 1.27 の発表資料リポジトリ issues.md §6・§7
  • dominikh/go-tools #1711
  • #79427

▸ ノート一覧に戻る