ダミー型パラメータによる instantiation cycle 回避
monomorphization checker が引き起こす instantiation cycle エラーには、実際に動く回避策が存在する。csgura が #80172 (2026-07-08) で示したもので、ダミーの型パラメータを1個足してメソッドをジェネリクスメソッド化すると通る。
type Phantom[T any] = *T
func (Slice[A]) Chunked[_ Phantom[A]](n int) Slice[[]A]
型引数は推論されるので、呼び出し側は何も書かなくてよい。素通りするダミーの型パラメータ _ を足すだけで、monomorphization checker の対象から外れる。
csgura はこの回避策と同時に、制限そのものへの反論も述べている。「ジェネリクスメソッドは呼ばれるまで instantiate されないのに、なぜ宣言時にエラーになるのか」というものだ。次のような例で Slice[A].Zip を instantiate するのに Slice[Tuple[A, B]].Zip の instantiate まで要求されるのはおかしい、という主張である。
type Slice[A any] []A
func (r Slice[A]) Zip[B any](other Slice[B]) Slice[Tuple[A, B]] { panic("") }
しかし Go チームはこの回避策を推奨していない。2026-08-12 の mrkfrmn の結論はこうだ。
On further thought and discussion with team members, we are unlikely to change this, at least for now.
理由は主に2つ。ひとつは、ダミー型パラメータを足すくらいなら素直に関数へ昇格させるべきというもの。もうひとつは、制限を緩和すると chunk() は落ちるのに chunk[_ any]() なら通る、という一貫性のない状態になり混乱を招く、というものだ。ジェネリクスメソッドは interface を満たさない (ジェネリクスメソッドはインターフェースを満たさない) ので理屈上は制限を外せる余地があるにもかかわらず、「混乱を避ける」という運用上の判断が優先された形になる。
具体的な症状の経緯 (griesemer の最小再現や f は通り m は落ちる対比) は 関数だと通りメソッドだと通らないシグネチャ に、制限そのものの原理は monomorphization checker にまとめてある。
出典
- Go Release Party 1.27 の発表資料リポジトリ
memo.md§1、issues.md§2 - #80172