go/types, types2: include type arguments in instantiated type cycle errors

When reporting layout cycles involving instantiated generic types, the
error chain omitted type arguments, making the output confusing since
the generic type itself makes no reference to the recursive type.

Fixes #75022

Change-Id: Ibd2c22afd9dbab03ab1df80d41e50b8cc5514ff0
GitHub-Last-Rev: 62264fd273
GitHub-Pull-Request: golang/go#78006
Reviewed-on: https://go-review.googlesource.com/c/go/+/752580
TryBot-Bypass: Mark Freeman <markfreeman@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
This commit is contained in:
davidteather 2026-05-06 02:15:29 +00:00 committed by Gopher Robot
parent 3cf84263ec
commit eb845eca72
4 changed files with 31 additions and 1 deletions

View file

@ -255,6 +255,10 @@ func (check *Checker) cycleError(cycle []Object, start int) {
// may refer to imported types. See go.dev/issue/50788.
// TODO(gri) This functionality is used elsewhere. Factor it out.
name := func(obj Object) string {
// include any type arguments in the reported error message
if n := asNamed(obj.Type()); n != nil && n.inst != nil {
return TypeString(n, check.qualifier)
}
return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
}

View file

@ -257,6 +257,10 @@ func (check *Checker) cycleError(cycle []Object, start int) {
// may refer to imported types. See go.dev/issue/50788.
// TODO(gri) This functionality is used elsewhere. Factor it out.
name := func(obj Object) string {
// include any type arguments in the reported error message
if n := asNamed(obj.Type()); n != nil && n.inst != nil {
return TypeString(n, check.qualifier)
}
return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
}

View file

@ -6,4 +6,6 @@ package b
import "./a"
type T a.T[T] // ERROR "invalid recursive type T\n.*T refers to a\.T\n.*a\.T refers to T"
type T a.T[T] // ERROR "invalid recursive type T\n.*T refers to a\.T\[T\]\n.*a\.T\[T\] refers to T"
type U a.T[a.T[U]] // ERROR "invalid recursive type U\n.*U refers to a\.T\[a\.T\[U\]\]\n.*a\.T\[a\.T\[U\]\] refers to a\.T\[U\]\n.*a\.T\[U\] refers to U"

View file

@ -0,0 +1,20 @@
// errorcheck
// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
type T[P any] struct {
_ P
}
type A T[A] // ERROR "invalid recursive type A\n.*A refers to T\[A\]\n.*T\[A\] refers to A"
type B = C
type C T[B] // ERROR "invalid recursive type C\n.*C refers to T\[B\]\n.*T\[B\] refers to C"
type D = T[D] // ERROR "invalid recursive type: D refers to itself"
type E T[T[E]] // ERROR "invalid recursive type E\n.*E refers to T\[T\[E\]\]\n.*T\[T\[E\]\] refers to T\[E\]\n.*T\[E\] refers to E"