]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: clarify a comment and add an extra test
authorRobert Griesemer <gri@golang.org>
Mon, 28 Feb 2022 05:08:29 +0000 (21:08 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 1 Mar 2022 23:49:01 +0000 (23:49 +0000)
Confirm that the current implementation of core type unification
looks correct and update the respective comment. Add an extra test.

Fixes #51376.

Change-Id: I6a603a4baeee2ede5bb4a1d60766204a808936d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/388294
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/types2/testdata/fixedbugs/issue51376.go2 [new file with mode: 0644]
src/cmd/compile/internal/types2/unify.go
src/go/types/testdata/fixedbugs/issue51376.go2 [new file with mode: 0644]
src/go/types/unify.go

diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51376.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51376.go2
new file mode 100644 (file)
index 0000000..4eba071
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2022 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 Map map[string]int
+
+func f[M ~map[K]V, K comparable, V any](M) {}
+func g[M map[K]V, K comparable, V any](M) {}
+
+func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() {
+        var m1 M1
+        f(m1)
+        g( /* ERROR M1 does not implement map\[K\]V */ m1) // M1 has tilde
+
+        var m2 M2
+        f(m2)
+        g(m2) // M1 does not have tilde
+
+        var m3 Map
+        f(m3)
+        g( /* ERROR Map does not implement map\[string\]int */ m3) // M in g does not have tilde
+}
index 03a9534c94f93f7cc5fbcf2d3f09283409882b67..97d327cf8b07ededf8d60ebbf1c9c2139ccd4eb9 100644 (file)
@@ -359,17 +359,17 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
        // (see issue #50755 for a test case).
        if enableCoreTypeUnification && !u.exact {
                if isTypeParam(x) && !hasName(y) {
-                       // Caution: This may not be correct in light of ~ constraints.
-                       //          See issue #51376.
-                       // TODO(gri) investigate!
-                       //
                        // When considering the type parameter for unification
-                       // we look at the adjusted core type (coreTerm).
+                       // we look at the adjusted core term (adjusted core type
+                       // with tilde information).
                        // If the adjusted core type is a named type N; the
                        // corresponding core type is under(N). Since !u.exact
                        // and y doesn't have a name, unification will end up
                        // comparing under(N) to y, so we can just use the core
-                       // type instead. Optimization.
+                       // type instead. And we can ignore the tilde because we
+                       // already look at the underlying types on both sides
+                       // and we have known types on both sides.
+                       // Optimization.
                        if cx := coreType(x); cx != nil {
                                if traceInference {
                                        u.tracef("core %s ≡ %s", x, y)
diff --git a/src/go/types/testdata/fixedbugs/issue51376.go2 b/src/go/types/testdata/fixedbugs/issue51376.go2
new file mode 100644 (file)
index 0000000..d51607b
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2022 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 Map map[string]int
+
+func f[M ~map[K]V, K comparable, V any](M) {}
+func g[M map[K]V, K comparable, V any](M) {}
+
+func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() {
+        var m1 M1
+        f(m1)
+        g /* ERROR M1 does not implement map\[K\]V */ (m1) // M1 has tilde
+
+        var m2 M2
+        f(m2)
+        g(m2) // M1 does not have tilde
+
+        var m3 Map
+        f(m3)
+        g /* ERROR Map does not implement map\[string\]int */ (m3) // M in g does not have tilde
+}
index e8d355ed317228ead4eb612ab67adbd745de6c7a..7b9aeeee0aea0f48ed12863e27d5dbe3219b7b55 100644 (file)
@@ -359,17 +359,17 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
        // (see issue #50755 for a test case).
        if enableCoreTypeUnification && !u.exact {
                if isTypeParam(x) && !hasName(y) {
-                       // Caution: This may not be correct in light of ~ constraints.
-                       //          See issue #51376.
-                       // TODO(gri) investigate!
-                       //
                        // When considering the type parameter for unification
-                       // we look at the adjusted core type (coreTerm).
+                       // we look at the adjusted core term (adjusted core type
+                       // with tilde information).
                        // If the adjusted core type is a named type N; the
                        // corresponding core type is under(N). Since !u.exact
                        // and y doesn't have a name, unification will end up
                        // comparing under(N) to y, so we can just use the core
-                       // type instead. Optimization.
+                       // type instead. And we can ignore the tilde because we
+                       // already look at the underlying types on both sides
+                       // and we have known types on both sides.
+                       // Optimization.
                        if cx := coreType(x); cx != nil {
                                if traceInference {
                                        u.tracef("core %s ≡ %s", x, y)