]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: avoid 2nd lookup when looking for method on ptr recv
authorRobert Griesemer <gri@golang.org>
Mon, 6 Mar 2023 03:44:34 +0000 (19:44 -0800)
committerGopher Robot <gobot@golang.org>
Mon, 6 Mar 2023 21:18:42 +0000 (21:18 +0000)
If a method is not found on a type V, for better error messages we
report if the method is on *V. There's no need to do a 2nd lookup
for that because the relevant information is readily returned by
lookupFieldOrMethod already.

Simplifies code and removes a long-standing TODO.

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

src/cmd/compile/internal/types2/lookup.go
src/go/types/lookup.go

index c19a6571c36288e2d362715e611440bf5eed4fb0..855bf2a24c1980465f54214e438cdce911679819 100644 (file)
@@ -349,7 +349,7 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
 
        state := ok
        var m *Func // method on T we're trying to implement
-       var f *Func // method on V, if found (state is one of ok, wrongName, wrongSig, ptrRecv)
+       var f *Func // method on V, if found (state is one of ok, wrongName, wrongSig)
 
        if u, _ := under(V).(*Interface); u != nil {
                tset := u.typeSet()
@@ -371,29 +371,21 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
                }
        } else {
                for _, m = range methods {
-                       obj, _, _ := lookupFieldOrMethodImpl(V, false, m.pkg, m.name, false)
+                       obj, _, indirect := lookupFieldOrMethodImpl(V, false, m.pkg, m.name, false)
 
                        // check if m is on *V, or on V with case-folding
                        if obj == nil {
-                               state = notFound
-                               // TODO(gri) Instead of NewPointer(V) below, can we just set the "addressable" argument?
-                               obj, _, _ = lookupFieldOrMethodImpl(NewPointer(V), false, m.pkg, m.name, false)
-                               if obj != nil {
-                                       f, _ = obj.(*Func)
-                                       if f != nil {
-                                               state = ptrRecv
-                                       }
-                                       // otherwise we found a field, keep state == notFound
+                               if indirect {
+                                       state = ptrRecv
                                        break
                                }
                                obj, _, _ = lookupFieldOrMethodImpl(V, false, m.pkg, m.name, true /* fold case */)
-                               if obj != nil {
-                                       f, _ = obj.(*Func)
-                                       if f != nil {
-                                               state = wrongName
-                                       }
-                                       // otherwise we found a (differently spelled) field, keep state == notFound
+                               f, _ = obj.(*Func)
+                               if f != nil {
+                                       state = wrongName
+                                       break
                                }
+                               state = notFound
                                break
                        }
 
index c59e5e6914042ff8a34ee72f9e6eb39a42adef0a..a2f7e7ea50e274c7fafded5ff65d66d6bb7792b3 100644 (file)
@@ -351,7 +351,7 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
 
        state := ok
        var m *Func // method on T we're trying to implement
-       var f *Func // method on V, if found (state is one of ok, wrongName, wrongSig, ptrRecv)
+       var f *Func // method on V, if found (state is one of ok, wrongName, wrongSig)
 
        if u, _ := under(V).(*Interface); u != nil {
                tset := u.typeSet()
@@ -373,29 +373,21 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
                }
        } else {
                for _, m = range methods {
-                       obj, _, _ := lookupFieldOrMethodImpl(V, false, m.pkg, m.name, false)
+                       obj, _, indirect := lookupFieldOrMethodImpl(V, false, m.pkg, m.name, false)
 
                        // check if m is on *V, or on V with case-folding
                        if obj == nil {
-                               state = notFound
-                               // TODO(gri) Instead of NewPointer(V) below, can we just set the "addressable" argument?
-                               obj, _, _ = lookupFieldOrMethodImpl(NewPointer(V), false, m.pkg, m.name, false)
-                               if obj != nil {
-                                       f, _ = obj.(*Func)
-                                       if f != nil {
-                                               state = ptrRecv
-                                       }
-                                       // otherwise we found a field, keep state == notFound
+                               if indirect {
+                                       state = ptrRecv
                                        break
                                }
                                obj, _, _ = lookupFieldOrMethodImpl(V, false, m.pkg, m.name, true /* fold case */)
-                               if obj != nil {
-                                       f, _ = obj.(*Func)
-                                       if f != nil {
-                                               state = wrongName
-                                       }
-                                       // otherwise we found a (differently spelled) field, keep state == notFound
+                               f, _ = obj.(*Func)
+                               if f != nil {
+                                       state = wrongName
+                                       break
                                }
+                               state = notFound
                                break
                        }