]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: always use missingMethodReason in checker.Implements
authorRobert Griesemer <gri@golang.org>
Fri, 4 Feb 2022 00:07:28 +0000 (16:07 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 4 Feb 2022 23:42:54 +0000 (23:42 +0000)
Remove special case where we don't have a *Checker and always use
Checker.missingMethodReason in Checker.implements.

Look for zero methods rather than empty interface to exit early
from Checker.missingMethod, and remove the extra test in
Checker.implements.

With this change we get consistent and more detailed error messages
from all places where we do a form of the "implements" test.

To make this possible, allow for the receiver to be nil in
- Checker.sprintf
- Checker.missingMethodReason
- Checker.interfacePtrError
- Checker.funcString

Allowing Checker.sprintf with nil Checker permits further simplifying
in a couple of places.

Change-Id: I0ea7178c9efbcd4a25ded2a66e2b058db52dc4d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/383054
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/errors.go
src/cmd/compile/internal/types2/instantiate.go
src/cmd/compile/internal/types2/lookup.go
src/cmd/compile/internal/types2/testdata/check/issues.src
src/cmd/compile/internal/types2/testdata/fixedbugs/issue49579.go2
src/go/types/errors.go
src/go/types/instantiate.go
src/go/types/lookup.go
src/go/types/testdata/check/issues.src
src/go/types/testdata/fixedbugs/issue49579.go2

index 2318b95f3d566b4074be6913d816263c21354ac7..77ae75a0a2a430d8aead8fd4cbe3801fb6a59950 100644 (file)
@@ -167,8 +167,13 @@ func (check *Checker) markImports(pkg *Package) {
        }
 }
 
+// check may be nil.
 func (check *Checker) sprintf(format string, args ...interface{}) string {
-       return sprintf(check.qualifier, false, format, args...)
+       var qf Qualifier
+       if check != nil {
+               qf = check.qualifier
+       }
+       return sprintf(qf, false, format, args...)
 }
 
 func (check *Checker) report(err *error_) {
index e0f2d8abe1d11fe1b50e5913a4f4044badd77d51..90a669f7541799ce7215a6e66f84e258a02f145c 100644 (file)
@@ -160,21 +160,17 @@ func (check *Checker) implements(V, T Type) error {
                return nil // avoid follow-on errors (see issue #49541 for an example)
        }
 
-       var qf Qualifier
-       if check != nil {
-               qf = check.qualifier
-       }
        errorf := func(format string, args ...interface{}) error {
-               return errors.New(sprintf(qf, false, format, args...))
+               return errors.New(check.sprintf(format, args...))
        }
 
        Ti, _ := Tu.(*Interface)
        if Ti == nil {
                var cause string
                if isInterfacePtr(Tu) {
-                       cause = sprintf(qf, false, "type %s is pointer to interface, not interface", T)
+                       cause = check.sprintf("type %s is pointer to interface, not interface", T)
                } else {
-                       cause = sprintf(qf, false, "%s is not an interface", T)
+                       cause = check.sprintf("%s is not an interface", T)
                }
                return errorf("%s does not implement %s (%s)", V, T, cause)
        }
@@ -199,23 +195,8 @@ func (check *Checker) implements(V, T Type) error {
        }
 
        // V must implement T's methods, if any.
-       if Ti.NumMethods() > 0 {
-               if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
-                       if check != nil && check.conf.CompilerErrorMessages {
-                               return errorf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
-                       }
-                       var cause string
-                       if wrong != nil {
-                               if Identical(m.typ, wrong.typ) {
-                                       cause = fmt.Sprintf("missing method %s (%s has pointer receiver)", m.name, m.name)
-                               } else {
-                                       cause = fmt.Sprintf("wrong type for method %s (have %s, want %s)", m.Name(), wrong.typ, m.typ)
-                               }
-                       } else {
-                               cause = "missing method " + m.Name()
-                       }
-                       return errorf("%s does not implement %s: %s", V, T, cause)
-               }
+       if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
+               return errorf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
        }
 
        // If T is comparable, V must be comparable.
index 1aeb2beaa02a3f9dd445f79eafb90c1a194b4615..7e528fb1aab7acd6c0478cb022f1c0885446a1fc 100644 (file)
@@ -297,7 +297,7 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b
 // as the second result.
 func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, alt *Func) {
        // fast path for common case
-       if T.Empty() {
+       if T.NumMethods() == 0 {
                return
        }
 
@@ -368,9 +368,10 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
 // and may include more have/want info after that. If non-nil, alt is a relevant
 // method that matches in some way. It may have the correct name, but wrong type, or
 // it may have a pointer receiver, or it may have the correct name except wrong case.
+// check may be nil.
 func (check *Checker) missingMethodReason(V, T Type, m, alt *Func) string {
        var mname string
-       if check.conf.CompilerErrorMessages {
+       if check != nil && check.conf.CompilerErrorMessages {
                mname = m.Name() + " method"
        } else {
                mname = "method " + m.Name()
@@ -406,6 +407,7 @@ func isInterfacePtr(T Type) bool {
        return p != nil && IsInterface(p.base)
 }
 
+// check may be nil.
 func (check *Checker) interfacePtrError(T Type) string {
        assert(isInterfacePtr(T))
        if p, _ := under(T).(*Pointer); isTypeParam(p.base) {
@@ -415,9 +417,14 @@ func (check *Checker) interfacePtrError(T Type) string {
 }
 
 // funcString returns a string of the form name + signature for f.
+// check may be nil.
 func (check *Checker) funcString(f *Func) string {
        buf := bytes.NewBufferString(f.name)
-       WriteSignature(buf, f.typ.(*Signature), check.qualifier)
+       var qf Qualifier
+       if check != nil {
+               qf = check.qualifier
+       }
+       WriteSignature(buf, f.typ.(*Signature), qf)
        return buf.String()
 }
 
index 3b27e0358547405e0adebd64b5a5c97caa3c6704..42c5bc8f128e891c7b14e6800022b0d406a4ee63 100644 (file)
@@ -131,7 +131,7 @@ func issue10260() {
        )
 
        var x I1
-       x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
+       x = T1 /* ERROR cannot use T1{} .* as I1 value in assignment: T1 does not implement I1 \(method foo has pointer receiver\) */ {}
        _ = x /* ERROR impossible type assertion: x\.\(T1\)\n\tT1 does not implement I1 \(method foo has pointer receiver\) */ .(T1)
 
        T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
@@ -139,34 +139,34 @@ func issue10260() {
 
        _ = i2 /* ERROR impossible type assertion: i2\.\(\*T1\)\n\t\*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ .(*T1)
 
-       i1 = i0 /* ERROR cannot use .* missing method foo */
-       i1 = t0 /* ERROR cannot use .* missing method foo */
-       i1 = i2 /* ERROR cannot use .* wrong type for method foo */
-       i1 = t2 /* ERROR cannot use .* wrong type for method foo */
-       i2 = i1 /* ERROR cannot use .* wrong type for method foo */
-       i2 = t1 /* ERROR cannot use .* wrong type for method foo */
+       i1 = i0 /* ERROR cannot use i0 .* as I1 value in assignment: I0 does not implement I1 \(missing method foo\) */
+       i1 = t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */
+       i1 = i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
+       i1 = t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
+       i2 = i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
+       i2 = t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
 
-       _ = func() I1 { return i0 /* ERROR cannot use .* missing method foo */ }
-       _ = func() I1 { return t0 /* ERROR cannot use .* missing method foo */ }
-       _ = func() I1 { return i2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = func() I1 { return t2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = func() I2 { return i1 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = func() I2 { return t1 /* ERROR cannot use .* wrong type for method foo */ }
+       _ = func() I1 { return i0 /* ERROR cannot use i0 .* as I1 value in return statement: I0 does not implement I1 \(missing method foo\) */ }
+       _ = func() I1 { return t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ }
+       _ = func() I1 { return i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
+       _ = func() I1 { return t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
+       _ = func() I2 { return i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
+       _ = func() I2 { return t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
 
        // a few more - less exhaustive now
 
        f := func(I1, I2){}
-       f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo \(have func\(\), want func\(x int\)\) */ )
+       f(i0 /* ERROR missing method foo */ , i1 /* ERROR wrong type for method foo */ )
 
-       _ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ }
-       _ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = []I1{i0 /* ERROR cannot use .* missing method foo */ }
-       _ = []I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ }
-       _ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ }
+       _ = [...]I1{i0 /* ERROR cannot use i0 .* as I1 value in array or slice literal: I0 does not implement I1 \(missing method foo\) */ }
+       _ = [...]I1{i2 /* ERROR cannot use i2 .* as I1 value in array or slice literal: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
+       _ = []I1{i0 /* ERROR missing method foo */ }
+       _ = []I1{i2 /* ERROR wrong type for method foo */ }
+       _ = map[int]I1{0: i0 /* ERROR missing method foo */ }
+       _ = map[int]I1{0: i2 /* ERROR wrong type for method foo */ }
 
-       make(chan I1) <- i0 /* ERROR I0 does not implement I1: missing method foo */
-       make(chan I1) <- i2 /* ERROR wrong type for method foo \(have func\(x int\), want func\(\)\) */
+       make(chan I1) <- i0 /* ERROR missing method foo */
+       make(chan I1) <- i2 /* ERROR wrong type for method foo */
 }
 
 // Check that constants representable as integers are in integer form
index 9e20ae5468db76e8604dcd93cea7c74f05480c8d..ee2d94ab8921fc11d587091e01f790916555d936 100644 (file)
@@ -9,7 +9,7 @@ type I[F any] interface {
 }
 
 func G[F any]() I[any] {
-       return g /* ERROR "missing method Q \(Q has pointer receiver\)" */ [F]{}
+       return g /* ERROR cannot use g\[F\]{} .* as I\[any\] value in return statement: g\[F\] does not implement I\[any\] \(method Q has pointer receiver\) */ [F]{}
 }
 
 type g[F any] struct{}
index ce62a8cbddd972da2b1da365e27cbc8c4cfb2bd3..a1786ec0ff33f8ea6ff15816655e06cc0c712154 100644 (file)
@@ -63,8 +63,15 @@ func (check *Checker) markImports(pkg *Package) {
        }
 }
 
+// check may be nil.
 func (check *Checker) sprintf(format string, args ...any) string {
-       return sprintf(check.fset, check.qualifier, false, format, args...)
+       var fset *token.FileSet
+       var qf Qualifier
+       if check != nil {
+               fset = check.fset
+               qf = check.qualifier
+       }
+       return sprintf(fset, qf, false, format, args...)
 }
 
 func sprintf(fset *token.FileSet, qf Qualifier, debug bool, format string, args ...any) string {
index 347815f9dd57618065bf90b50dab66e91f6845a6..aeb30fa412ee2bc14ffad09c3093ebca1843a06a 100644 (file)
@@ -160,25 +160,17 @@ func (check *Checker) implements(V, T Type) error {
                return nil // avoid follow-on errors (see issue #49541 for an example)
        }
 
-       var qf Qualifier
-       if check != nil {
-               qf = check.qualifier
-       }
        errorf := func(format string, args ...any) error {
-               return errors.New(sprintf(nil, qf, false, format, args...))
+               return errors.New(check.sprintf(format, args...))
        }
 
        Ti, _ := Tu.(*Interface)
        if Ti == nil {
-               var fset *token.FileSet
-               if check != nil {
-                       fset = check.fset
-               }
                var cause string
                if isInterfacePtr(Tu) {
-                       cause = sprintf(fset, qf, false, "type %s is pointer to interface, not interface", T)
+                       cause = check.sprintf("type %s is pointer to interface, not interface", T)
                } else {
-                       cause = sprintf(fset, qf, false, "%s is not an interface", T)
+                       cause = check.sprintf("%s is not an interface", T)
                }
                return errorf("%s does not implement %s (%s)", V, T, cause)
        }
@@ -203,23 +195,8 @@ func (check *Checker) implements(V, T Type) error {
        }
 
        // V must implement T's methods, if any.
-       if Ti.NumMethods() > 0 {
-               if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
-                       if check != nil && compilerErrorMessages {
-                               return errorf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
-                       }
-                       var cause string
-                       if wrong != nil {
-                               if Identical(m.typ, wrong.typ) {
-                                       cause = fmt.Sprintf("missing method %s (%s has pointer receiver)", m.name, m.name)
-                               } else {
-                                       cause = fmt.Sprintf("wrong type for method %s (have %s, want %s)", m.Name(), wrong.typ, m.typ)
-                               }
-                       } else {
-                               cause = "missing method " + m.Name()
-                       }
-                       return errorf("%s does not implement %s: %s", V, T, cause)
-               }
+       if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
+               return errorf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
        }
 
        // If T is comparable, V must be comparable.
index 1b4f953803100df4ff298f009d7a0b32637081a8..ad5438aefbf2b723189c9cc291b47ef1cf6962be 100644 (file)
@@ -298,7 +298,7 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b
 // Note: case-folding lookup is currently disabled
 func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, alt *Func) {
        // fast path for common case
-       if T.Empty() {
+       if T.NumMethods() == 0 {
                return
        }
 
@@ -370,9 +370,10 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
 // and may include more have/want info after that. If non-nil, alt is a relevant
 // method that matches in some way. It may have the correct name, but wrong type, or
 // it may have a pointer receiver, or it may have the correct name except wrong case.
+// check may be nil.
 func (check *Checker) missingMethodReason(V, T Type, m, alt *Func) string {
        var mname string
-       if compilerErrorMessages {
+       if check != nil && compilerErrorMessages {
                mname = m.Name() + " method"
        } else {
                mname = "method " + m.Name()
@@ -408,6 +409,7 @@ func isInterfacePtr(T Type) bool {
        return p != nil && IsInterface(p.base)
 }
 
+// check may be nil.
 func (check *Checker) interfacePtrError(T Type) string {
        assert(isInterfacePtr(T))
        if p, _ := under(T).(*Pointer); isTypeParam(p.base) {
@@ -416,10 +418,14 @@ func (check *Checker) interfacePtrError(T Type) string {
        return check.sprintf("type %s is pointer to interface, not interface", T)
 }
 
-// funcString returns a string of the form name + signature for f.
+// check may be nil.
 func (check *Checker) funcString(f *Func) string {
        buf := bytes.NewBufferString(f.name)
-       WriteSignature(buf, f.typ.(*Signature), check.qualifier)
+       var qf Qualifier
+       if check != nil {
+               qf = check.qualifier
+       }
+       WriteSignature(buf, f.typ.(*Signature), qf)
        return buf.String()
 }
 
index ce27ac3cfb10aae1a48af3e81a257890917b66fd..8bb4c8c5cae088a55cb8b772e7c37ff620a71cb0 100644 (file)
@@ -131,7 +131,7 @@ func issue10260() {
        )
 
        var x I1
-       x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
+       x = T1 /* ERROR cannot use \(T1 literal\) .* as I1 value in assignment: T1 does not implement I1 \(method foo has pointer receiver\) */ {}
        _ = x /* ERROR impossible type assertion: x\.\(T1\)\n\tT1 does not implement I1 \(method foo has pointer receiver\) */ .(T1)
 
        T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
@@ -139,34 +139,34 @@ func issue10260() {
 
        _ = i2 /* ERROR impossible type assertion: i2\.\(\*T1\)\n\t\*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ .(*T1)
 
-       i1 = i0 /* ERROR cannot use .* missing method foo */
-       i1 = t0 /* ERROR cannot use .* missing method foo */
-       i1 = i2 /* ERROR cannot use .* wrong type for method foo */
-       i1 = t2 /* ERROR cannot use .* wrong type for method foo */
-       i2 = i1 /* ERROR cannot use .* wrong type for method foo */
-       i2 = t1 /* ERROR cannot use .* wrong type for method foo */
+       i1 = i0 /* ERROR cannot use i0 .* as I1 value in assignment: I0 does not implement I1 \(missing method foo\) */
+       i1 = t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */
+       i1 = i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
+       i1 = t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
+       i2 = i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
+       i2 = t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
 
-       _ = func() I1 { return i0 /* ERROR cannot use .* missing method foo */ }
-       _ = func() I1 { return t0 /* ERROR cannot use .* missing method foo */ }
-       _ = func() I1 { return i2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = func() I1 { return t2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = func() I2 { return i1 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = func() I2 { return t1 /* ERROR cannot use .* wrong type for method foo */ }
+       _ = func() I1 { return i0 /* ERROR cannot use i0 .* as I1 value in return statement: I0 does not implement I1 \(missing method foo\) */ }
+       _ = func() I1 { return t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ }
+       _ = func() I1 { return i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
+       _ = func() I1 { return t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
+       _ = func() I2 { return i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
+       _ = func() I2 { return t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
 
        // a few more - less exhaustive now
 
        f := func(I1, I2){}
-       f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo \(have func\(\), want func\(x int\)\) */ )
+       f(i0 /* ERROR missing method foo */ , i1 /* ERROR wrong type for method foo */ )
 
-       _ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ }
-       _ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = []I1{i0 /* ERROR cannot use .* missing method foo */ }
-       _ = []I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
-       _ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ }
-       _ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ }
+       _ = [...]I1{i0 /* ERROR cannot use i0 .* as I1 value in array or slice literal: I0 does not implement I1 \(missing method foo\) */ }
+       _ = [...]I1{i2 /* ERROR cannot use i2 .* as I1 value in array or slice literal: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
+       _ = []I1{i0 /* ERROR missing method foo */ }
+       _ = []I1{i2 /* ERROR wrong type for method foo */ }
+       _ = map[int]I1{0: i0 /* ERROR missing method foo */ }
+       _ = map[int]I1{0: i2 /* ERROR wrong type for method foo */ }
 
-       make(chan I1) <- i0 /* ERROR I0 does not implement I1: missing method foo */
-       make(chan I1) <- i2 /* ERROR wrong type for method foo \(have func\(x int\), want func\(\)\) */
+       make(chan I1) <- i0 /* ERROR missing method foo */
+       make(chan I1) <- i2 /* ERROR wrong type for method foo */
 }
 
 // Check that constants representable as integers are in integer form
index 9e20ae5468db76e8604dcd93cea7c74f05480c8d..07748bd0dc4798fe51a6dce73b7dded4589150c2 100644 (file)
@@ -9,7 +9,7 @@ type I[F any] interface {
 }
 
 func G[F any]() I[any] {
-       return g /* ERROR "missing method Q \(Q has pointer receiver\)" */ [F]{}
+       return g /* ERROR cannot use \(g\[F\] literal\) .* as I\[any\] value in return statement: g\[F\] does not implement I\[any\] \(method Q has pointer receiver\) */ [F]{}
 }
 
 type g[F any] struct{}