]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: avoid confusing error message "have m(T), want m(T)"
authorRobert Griesemer <gri@golang.org>
Tue, 12 Dec 2023 23:40:16 +0000 (15:40 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 13 Dec 2023 14:32:38 +0000 (14:32 +0000)
This is a partial fix for situations where a method lookup leads to
an error due to non-matching signatures, but where the signatures
print exactly the same. This can happen if both signatures contain
type parameters (after instantiation) and the type parameters have
the same name (such as "T").

For now, rather than printing a confusing error message in this
case, leave away the confusing part of the error message (at the
cost of providing slightly less information).

In the long run, we need to find a better solution for this problem;
but this seems better than what we had before.

For #61685.

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

src/cmd/compile/internal/types2/lookup.go
src/go/types/lookup.go
src/internal/types/testdata/fixedbugs/issue61685.go [new file with mode: 0644]

index 893cdb157dff2cc5d9b93c49f4e0fb7adf305794..014a5489cdaa38c8b636628ce9f7069dba19041e 100644 (file)
@@ -445,8 +445,18 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
                                // Add package information to disambiguate (go.dev/issue/54258).
                                fs, ms = check.funcString(f, true), check.funcString(m, true)
                        }
-                       *cause = check.sprintf("(wrong type for method %s)\n\t\thave %s\n\t\twant %s",
-                               m.Name(), fs, ms)
+                       if fs == ms {
+                               // We still have "want Foo, have Foo".
+                               // This is most likely due to different type parameters with
+                               // the same name appearing in the instantiated signatures
+                               // (go.dev/issue/61685).
+                               // Rather than reporting this misleading error cause, for now
+                               // just point out that the method signature is incorrect.
+                               // TODO(gri) should find a good way to report the root cause
+                               *cause = check.sprintf("(wrong type for method %s)", m.Name())
+                               break
+                       }
+                       *cause = check.sprintf("(wrong type for method %s)\n\t\thave %s\n\t\twant %s", m.Name(), fs, ms)
                case ambigSel:
                        *cause = check.sprintf("(ambiguous selector %s.%s)", V, m.Name())
                case ptrRecv:
index 2857ba358c19eb3283cb32a01fab4334943216c0..05d30c178a11ef7f36b9352b02d5f39c6aee5cdf 100644 (file)
@@ -447,8 +447,18 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
                                // Add package information to disambiguate (go.dev/issue/54258).
                                fs, ms = check.funcString(f, true), check.funcString(m, true)
                        }
-                       *cause = check.sprintf("(wrong type for method %s)\n\t\thave %s\n\t\twant %s",
-                               m.Name(), fs, ms)
+                       if fs == ms {
+                               // We still have "want Foo, have Foo".
+                               // This is most likely due to different type parameters with
+                               // the same name appearing in the instantiated signatures
+                               // (go.dev/issue/61685).
+                               // Rather than reporting this misleading error cause, for now
+                               // just point out that the method signature is incorrect.
+                               // TODO(gri) should find a good way to report the root cause
+                               *cause = check.sprintf("(wrong type for method %s)", m.Name())
+                               break
+                       }
+                       *cause = check.sprintf("(wrong type for method %s)\n\t\thave %s\n\t\twant %s", m.Name(), fs, ms)
                case ambigSel:
                        *cause = check.sprintf("(ambiguous selector %s.%s)", V, m.Name())
                case ptrRecv:
diff --git a/src/internal/types/testdata/fixedbugs/issue61685.go b/src/internal/types/testdata/fixedbugs/issue61685.go
new file mode 100644 (file)
index 0000000..b88b222
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2023 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 _[T any](x any) {
+       f /* ERROR "T (type I[T]) does not satisfy I[T] (wrong type for method m)" */ (x.(I[T]))
+}
+
+func f[T I[T]](T) {}
+
+type I[T any] interface {
+       m(T)
+}