diff options
author | Dan Scales <danscales@google.com> | 2022-01-08 10:33:35 -0800 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2022-01-11 22:50:23 +0000 |
commit | 1ee70da3125cb6339c1bcb0c127cd97a9e1dbe90 (patch) | |
tree | 68477aaf042b7eb9f693c3474dc88c33a7cd2e86 /src/cmd | |
parent | 13c912d19252b9225fa96b9a5557575bbaffb570 (diff) | |
download | go-1ee70da3125cb6339c1bcb0c127cd97a9e1dbe90.tar.gz go-1ee70da3125cb6339c1bcb0c127cd97a9e1dbe90.zip |
cmd/compile: fix the names of methods created during type substitution
The names given to methods of types created during type substitution
were possible incorrect when the type parameters themselves were nested
types.
Fixes #50485
Change-Id: I7e0043ed22c26406a5f9d8d51d9e928770a678f6
Reviewed-on: https://go-review.googlesource.com/c/go/+/377494
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r-- | src/cmd/compile/internal/typecheck/subr.go | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go index da5e9645ea..04a4ed392f 100644 --- a/src/cmd/compile/internal/typecheck/subr.go +++ b/src/cmd/compile/internal/typecheck/subr.go @@ -976,7 +976,9 @@ func makeInstName1(name string, targs []*types.Type, hasBrackets bool) string { // function that helps implement a method of an instantiated type). For method nodes // on shape types, we prepend "nofunc.", because method nodes for shape types will // have no body, and we want to avoid a name conflict with the shape-based function -// that helps implement the same method for fully-instantiated types. +// that helps implement the same method for fully-instantiated types. Function names +// are also created at the end of (*Tsubster).typ1, so we append "nofunc" there as +// well, as needed. func MakeFuncInstSym(gf *types.Sym, targs []*types.Type, isMethodNode, hasBrackets bool) *types.Sym { nm := makeInstName1(gf.Name, targs, hasBrackets) if targs[0].HasShape() && isMethodNode { @@ -1273,7 +1275,25 @@ func (ts *Tsubster) typ1(t *types.Type) *types.Type { for i, f := range t.Methods().Slice() { t2 := ts.typ1(f.Type) oldsym := f.Nname.Sym() - newsym := MakeFuncInstSym(oldsym, ts.Targs, true, true) + + // Use the name of the substituted receiver to create the + // method name, since the receiver name may have many levels + // of nesting (brackets) with type names to be substituted. + recvType := t2.Recv().Type + var nm string + if recvType.IsPtr() { + recvType = recvType.Elem() + nm = "(*" + recvType.Sym().Name + ")." + f.Sym.Name + } else { + nm = recvType.Sym().Name + "." + f.Sym.Name + } + if recvType.RParams()[0].HasShape() { + // We add "nofunc" to methods of shape type to avoid + // conflict with the name of the shape-based helper + // function. See header comment of MakeFuncInstSym. + nm = "nofunc." + nm + } + newsym := oldsym.Pkg.Lookup(nm) var nname *ir.Name if newsym.Def != nil { nname = newsym.Def.(*ir.Name) |