spec: remove cycle restriction for type parameters

Fixes #75883.

Change-Id: I708c0594ef3182d3aca37a6358aa0a0ef89809b6
Reviewed-on: https://go-review.googlesource.com/c/go/+/711422
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Robert Griesemer 2025-10-13 16:57:34 -07:00 committed by Gopher Robot
parent 0f9c8fb29d
commit 4684a26c26
2 changed files with 21 additions and 17 deletions

View file

@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
"Subtitle": "Language version go1.26 (Nov 9, 2025)",
"Subtitle": "Language version go1.26 (Nov 12, 2025)",
"Path": "/ref/spec"
}-->
@ -2686,22 +2686,6 @@ of a <a href="#Method_declarations">method declaration</a> associated
with a generic type.
</p>
<p>
Within a type parameter list of a generic type <code>T</code>, a type constraint
may not (directly, or indirectly through the type parameter list of another
generic type) refer to <code>T</code>.
</p>
<pre>
type T1[P T1[P]] … // illegal: T1 refers to itself
type T2[P interface{ T2[int] }] … // illegal: T2 refers to itself
type T3[P interface{ m(T3[int])}] … // illegal: T3 refers to itself
type T4[P T5[P]] … // illegal: T4 refers to T5 and
type T5[P T4[P]] … // T5 refers to T4
type T6[P int] struct{ f *T6[P] } // ok: reference to T6 is not in type parameter list
</pre>
<h4 id="Type_constraints">Type constraints</h4>
<p>

View file

@ -0,0 +1,20 @@
// Copyright 2025 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.
// Test cases that were invalid because of cycles before the respective language change.
// Some are still invalid, but not because of cycles.
package p
type T1[P T1[P]] struct{}
type T2[P interface {
T2[int /* ERROR "int does not satisfy interface{T2[int]}" */]
}] struct{}
type T3[P interface {
m(T3[int /* ERROR "int does not satisfy interface{m(T3[int])}" */])
}] struct{}
type T4[P T5[P /* ERROR "P does not satisfy T4[P]" */]] struct{}
type T5[P T4[P /* ERROR "P does not satisfy T5[P]" */]] struct{}
type T6[P int] struct{ f *T6[P] }