go/types: partial revert of incorrect unification "fix"
This is a port of CL 354690 from types2 to go/types.
Change-Id: I50e7297a67e37d261335260e285b9cb1c0d2a62d
Reviewed-on: https://go-review.googlesource.com/c/go/+/354691
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/src/go/types/testdata/fixedbugs/issue48619.go2 b/src/go/types/testdata/fixedbugs/issue48619.go2
index 24650a3..870bacd 100644
--- a/src/go/types/testdata/fixedbugs/issue48619.go2
+++ b/src/go/types/testdata/fixedbugs/issue48619.go2
@@ -2,21 +2,23 @@
// 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.
+
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
+ // 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)
+ // g(&a, &b)
+ // g([]P{}, []P{})
}
func h[P any](a, b P) {
- h(&a, &b)
- h([]P{a}, []P{b})
+ // h(&a, &b)
+ // h([]P{a}, []P{b})
}
diff --git a/src/go/types/testdata/fixedbugs/issue48656.go2 b/src/go/types/testdata/fixedbugs/issue48656.go2
index ee639e1..52863d4 100644
--- a/src/go/types/testdata/fixedbugs/issue48656.go2
+++ b/src/go/types/testdata/fixedbugs/issue48656.go2
@@ -2,12 +2,11 @@
// 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.
+
package p
-// TODO(gri) Still need better error positions and message here.
-// But this doesn't crash anymore.
-
-func f[P /* ERROR does not match \*Q */ interface{*Q}, Q any](p P, q Q) {
- _ = f[P]
- _ = f /* ERROR cannot infer P */ [*P]
+func f[P interface{*Q}, Q any](p P, q Q) {
+ // _ = f[P]
+ // _ = f[/* ERROR cannot infer P */ *P]
}
diff --git a/src/go/types/testdata/fixedbugs/issue48695.go2 b/src/go/types/testdata/fixedbugs/issue48695.go2
new file mode 100644
index 0000000..2d9e6a5
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue48695.go2
@@ -0,0 +1,14 @@
+// Copyright 2021 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
+
+func g[P interface{~func(T) P}, T any](P) {}
+
+func _() {
+ type F func(int) F
+ var f F
+ g(f)
+ _ = g[F]
+}
diff --git a/src/go/types/unify.go b/src/go/types/unify.go
index 984ba59..99c9c9e 100644
--- a/src/go/types/unify.go
+++ b/src/go/types/unify.go
@@ -63,10 +63,6 @@
type tparamsList struct {
unifier *unifier
tparams []*TypeParam
- // For each tparams element, there is a corresponding mask bit in masks.
- // If set, the corresponding type parameter is masked and doesn't appear
- // as a type parameter with tparamsList.index.
- masks []bool
// For each tparams element, there is a corresponding type slot index in indices.
// index < 0: unifier.types[-index-1] == nil
// index == 0: no type slot allocated yet
@@ -107,14 +103,9 @@
}
}
d.tparams = tparams
- d.masks = make([]bool, len(tparams))
d.indices = make([]int, len(tparams))
}
-// mask and unmask permit the masking/unmasking of the i'th type parameter of d.
-func (d *tparamsList) mask(i int) { d.masks[i] = true }
-func (d *tparamsList) unmask(i int) { d.masks[i] = false }
-
// join unifies the i'th type parameter of x with the j'th type parameter of y.
// If both type parameters already have a type associated with them and they are
// not joined, join fails and returns false.
@@ -158,13 +149,11 @@
return true
}
-// If typ is an unmasked type parameter of d, index returns the type parameter index.
+// If typ is a type parameter of d, index returns the type parameter index.
// Otherwise, the result is < 0.
func (d *tparamsList) index(typ Type) int {
if tpar, ok := typ.(*TypeParam); ok {
- if i := tparamIndex(d.tparams, tpar); i >= 0 && !d.masks[i] {
- return i
- }
+ return tparamIndex(d.tparams, tpar)
}
return -1
}
@@ -257,7 +246,7 @@
}
}
- // Cases where at least one of x or y is an (unmasked) type parameter.
+ // Cases where at least one of x or y is a type parameter.
switch i, j := u.x.index(x), u.y.index(y); {
case i >= 0 && j >= 0:
// both x and y are type parameters
@@ -270,12 +259,6 @@
case i >= 0:
// x is a type parameter, y is not
if tx := u.x.at(i); tx != nil {
- // The inferred type tx may be or contain x again but we don't
- // want to "unpack" it again when unifying tx with y: tx is the
- // inferred type. Mask type parameter x for this recursion, so
- // that subsequent encounters treat x like an ordinary type.
- u.x.mask(i)
- defer u.x.unmask(i)
return u.nifyEq(tx, y, p)
}
// otherwise, infer type from y
@@ -285,9 +268,6 @@
case j >= 0:
// y is a type parameter, x is not
if ty := u.y.at(j); ty != nil {
- // see comment above
- u.y.mask(j)
- defer u.y.unmask(j)
return u.nifyEq(x, ty, p)
}
// otherwise, infer type from x