]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fixes for pointer receivers of instantiated methods
authorRobert Griesemer <gri@golang.org>
Tue, 21 Sep 2021 00:56:35 +0000 (17:56 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 21 Sep 2021 03:15:20 +0000 (03:15 +0000)
Backported changes from CL 349998 that were not already in go/types.

Change-Id: I0341f76c080b4e73567b3e917a4cbbe2e82d3703
Reviewed-on: https://go-review.googlesource.com/c/go/+/351149
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>
src/go/types/instantiate_test.go
src/go/types/named.go

index 0c66acb8750c4b4c325e03c248ae6fb46b7d2219..cf6d2a9198688a6de13b020e392f4b734fc953c4 100644 (file)
@@ -86,7 +86,7 @@ var X T[int]
        }{
                {"func (r T[P]) m() P", "func (T[int]).m() int"},
                {"func (r T[P]) m(P)", "func (T[int]).m(int)"},
-               {"func (r T[P]) m() func() P", "func (T[int]).m() func() int"},
+               {"func (r *T[P]) m(P)", "func (*T[int]).m(int)"},
                {"func (r T[P]) m() T[P]", "func (T[int]).m() T[int]"},
                {"func (r T[P]) m(T[P])", "func (T[int]).m(T[int])"},
                {"func (r T[P]) m(T[P], P, string)", "func (T[int]).m(T[int], int, string)"},
@@ -99,7 +99,7 @@ var X T[int]
                if err != nil {
                        t.Fatal(err)
                }
-               typ := pkg.Scope().Lookup("X").Type().(*Named)
+               typ := NewPointer(pkg.Scope().Lookup("X").Type())
                obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
                m, _ := obj.(*Func)
                if m == nil {
index 302e43174e6ffe80a738037b0909941f978a3016..1815aad0141c57658c990f1a36ab040d1c75ac3c 100644 (file)
@@ -257,7 +257,7 @@ func expandNamed(env *Environment, n *Named, instPos token.Pos) (tparams *TypePa
                        // During type checking origm may not have a fully set up type, so defer
                        // instantiation of its signature until later.
                        m := NewFunc(origm.pos, origm.pkg, origm.name, nil)
-                       m.hasPtrRecv = origm.hasPtrRecv
+                       m.hasPtrRecv = ptrRecv(origm)
                        // Setting instRecv here allows us to complete later (we need the
                        // instRecv to get targs and the original method).
                        m.instRecv = n
@@ -289,32 +289,38 @@ func expandNamed(env *Environment, n *Named, instPos token.Pos) (tparams *TypePa
 
 func (check *Checker) completeMethod(env *Environment, m *Func) {
        assert(m.instRecv != nil)
-       rtyp := m.instRecv
+       rbase := m.instRecv
        m.instRecv = nil
        m.setColor(black)
 
-       assert(rtyp.TypeArgs().Len() > 0)
+       assert(rbase.TypeArgs().Len() > 0)
 
        // Look up the original method.
-       _, orig := lookupMethod(rtyp.orig.methods, rtyp.obj.pkg, m.name)
+       _, orig := lookupMethod(rbase.orig.methods, rbase.obj.pkg, m.name)
        assert(orig != nil)
        if check != nil {
                check.objDecl(orig, nil)
        }
        origSig := orig.typ.(*Signature)
-       if origSig.RecvTypeParams().Len() != rtyp.targs.Len() {
+       if origSig.RecvTypeParams().Len() != rbase.targs.Len() {
                m.typ = origSig // or new(Signature), but we can't use Typ[Invalid]: Funcs must have Signature type
                return          // error reported elsewhere
        }
 
-       smap := makeSubstMap(origSig.RecvTypeParams().list(), rtyp.targs.list())
+       smap := makeSubstMap(origSig.RecvTypeParams().list(), rbase.targs.list())
        sig := check.subst(orig.pos, origSig, smap, env).(*Signature)
        if sig == origSig {
-               // No substitution occurred, but we still need to create a copy to hold the
-               // instantiated receiver.
+               // No substitution occurred, but we still need to create a new signature to
+               // hold the instantiated receiver.
                copy := *origSig
                sig = &copy
        }
+       var rtyp Type
+       if ptrRecv(m) {
+               rtyp = NewPointer(rbase)
+       } else {
+               rtyp = rbase
+       }
        sig.recv = NewParam(origSig.recv.pos, origSig.recv.pkg, origSig.recv.name, rtyp)
 
        m.typ = sig