// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This issue has been re-opened.
+// This issue is still open:
+// - the error messages could be better or are incorrect
+// - unification fails due to stack overflow that is caught
package p
func f[P any](a, _ P) {
- // var x int
- // f(a, x /* ERROR type int of x does not match P */)
- // f(x, a /* ERROR type P of a does not match inferred type int for P */)
+ var x int
+ // TODO(gri) these error messages, while correct, could be better
+ f(a, x /* ERROR type int of x does not match P */)
+ f(x, a /* ERROR type P of a does not match inferred type int for P */)
}
func g[P any](a, b P) {
- // g(a, b)
- // g(&a, &b)
- // g([]P{}, []P{})
-}
+ g(a, b)
+ // TODO(gri) these error messages are incorrect because the code is valid
+ g(&a, & /* ERROR type \*P of &b does not match inferred type \*P for P */ b)
+ g([]P{}, [ /* ERROR type \[\]P of \[\]P{} does not match inferred type \[\]P for P */ ]P{})
-func h[P any](a, b P) {
- // h(&a, &b)
- // h([]P{a}, []P{b})
+ // work-around: provide type argument explicitly
+ g[*P](&a, &b)
+ g[[]P]([]P{}, []P{})
}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This issue is still open.
+// This issue is still open:
+// - the error messages are unclear
+// - unification fails due to stack overflow that is caught
package p
-func f[P *Q, Q any](p P, q Q) {
- // _ = f[P]
- // _ = f[/* ERROR cannot infer P */ *P]
+func f[P *Q, Q any](P, Q) {
+ // TODO(gri) these error messages are unclear
+ _ = f[ /* ERROR P does not match \*Q */ P]
+ _ = f[ /* ERROR cannot infer P */ *P]
}
// by setting up one of them (using init) and then assigning its value
// to the other.
+// Upper limit for recursion depth. Used to catch infinite recursions
+// due to implementation issues (e.g., see issues #48619, #48656).
+const unificationDepthLimit = 50
+
// A unifier maintains the current type parameters for x and y
// and the respective types inferred for each type parameter.
// A unifier is created by calling newUnifier.
exact bool
x, y tparamsList // x and y must initialized via tparamsList.init
types []Type // inferred types, shared by x and y
+ depth int // recursion depth during unification
}
// newUnifier returns a new unifier.
// code the corresponding changes should be made here.
// Must not be called directly from outside the unifier.
func (u *unifier) nify(x, y Type, p *ifacePair) bool {
+ // Stop gap for cases where unification fails.
+ if u.depth >= unificationDepthLimit {
+ if debug {
+ panic("unification reached recursion depth limit")
+ }
+ return false
+ }
+ u.depth++
+ defer func() {
+ u.depth--
+ }()
+
if !u.exact {
// If exact unification is known to fail because we attempt to
// match a type name against an unnamed type literal, consider
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This issue has been re-opened.
+// This issue is still open:
+// - the error messages could be better or are incorrect
+// - unification fails due to stack overflow that is caught
package p
func f[P any](a, _ P) {
- // var x int
- // f(a, x /* ERROR type int of x does not match P */)
- // f(x, a /* ERROR type P of a does not match inferred type int for P */)
+ var x int
+ // TODO(gri) these error messages, while correct, could be better
+ f(a, x /* ERROR type int of x does not match P */)
+ f(x, a /* ERROR type P of a does not match inferred type int for P */)
}
func g[P any](a, b P) {
- // g(a, b)
- // g(&a, &b)
- // g([]P{}, []P{})
-}
+ g(a, b)
+ // TODO(gri) these error messages are incorrect because the code is valid
+ g(&a, & /* ERROR type \*P of &b does not match inferred type \*P for P */ b)
+ g([]P{}, [ /* ERROR type \[\]P of \(\[\]P literal\) does not match inferred type \[\]P for P */ ]P{})
-func h[P any](a, b P) {
- // h(&a, &b)
- // h([]P{a}, []P{b})
+ // work-around: provide type argument explicitly
+ g[*P](&a, &b)
+ g[[]P]([]P{}, []P{})
}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This issue is still open.
+// This issue is still open:
+// - the error messages are unclear
+// - unification fails due to stack overflow that is caught
package p
-func f[P interface{*Q}, Q any](p P, q Q) {
- // _ = f[P]
- // _ = f[/* ERROR cannot infer P */ *P]
+func f[P *Q, Q any](P, Q) {
+ // TODO(gri) these error messages are unclear
+ _ = f /* ERROR P does not match \*Q */ [P]
+ _ = f /* ERROR cannot infer P */ [*P]
}
// by setting up one of them (using init) and then assigning its value
// to the other.
+// Upper limit for recursion depth. Used to catch infinite recursions
+// due to implementation issues (e.g., see issues #48619, #48656).
+const unificationDepthLimit = 50
+
// A unifier maintains the current type parameters for x and y
// and the respective types inferred for each type parameter.
// A unifier is created by calling newUnifier.
exact bool
x, y tparamsList // x and y must initialized via tparamsList.init
types []Type // inferred types, shared by x and y
+ depth int // recursion depth during unification
}
// newUnifier returns a new unifier.
// code the corresponding changes should be made here.
// Must not be called directly from outside the unifier.
func (u *unifier) nify(x, y Type, p *ifacePair) bool {
+ // Stop gap for cases where unification fails.
+ if u.depth >= unificationDepthLimit {
+ if debug {
+ panic("unification reached recursion depth limit")
+ }
+ return false
+ }
+ u.depth++
+ defer func() {
+ u.depth--
+ }()
+
if !u.exact {
// If exact unification is known to fail because we attempt to
// match a type name against an unnamed type literal, consider