aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/stencil.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-12-13 12:42:38 -0800
committerDan Scales <danscales@google.com>2021-12-13 22:45:26 +0000
commit5b9207ff67bd3df43a95fd403b2e06e2aa4c33bf (patch)
tree7680edfebd1ef0c0547a5324cc7cce00247a223f /src/cmd/compile/internal/noder/stencil.go
parent67917c3d78002ebca7de697f4ede74e602701554 (diff)
downloadgo-5b9207ff67bd3df43a95fd403b2e06e2aa4c33bf.tar.xz
cmd/compile: avoid re-instantiating method that is already imported
We can import an shape-instantiated function/method for inlining purposes. If we are instantiating the methods of a instantiated type that we have seen, and it happens to need a shape instantiation that we have imported, then don't re-create the instantiation, since we will end up with conflicting/duplicate definitions for the instantiation symbol. Instead, we can just use the existing imported instantation, and enter it in the instInfoMap[]. Fixes #50121 Change-Id: I6eeb8786faad71106e261e113048b579afad04fa Reviewed-on: https://go-review.googlesource.com/c/go/+/371414 Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/stencil.go')
-rw-r--r--src/cmd/compile/internal/noder/stencil.go19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index 004db54c3b..62c306b89e 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -684,7 +684,22 @@ func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMe
}
info.dictInfo.shapeToBound = make(map[*types.Type]*types.Type)
- // genericSubst fills in info.dictParam and info.tparamToBound.
+ if sym.Def != nil {
+ // This instantiation must have been imported from another
+ // package (because it was needed for inlining), so we should
+ // not re-generate it and have conflicting definitions for the
+ // symbol (issue #50121). It will have already gone through the
+ // dictionary transformations of dictPass, so we don't actually
+ // need the info.dictParam and info.shapeToBound info filled in
+ // below. We just set the imported instantiation as info.fun.
+ assert(sym.Pkg != types.LocalPkg)
+ info.fun = sym.Def.(*ir.Name).Func
+ assert(info.fun != nil)
+ g.instInfoMap[sym] = info
+ return info
+ }
+
+ // genericSubst fills in info.dictParam and info.shapeToBound.
st := g.genericSubst(sym, nameNode, shapes, isMeth, info)
info.fun = st
g.instInfoMap[sym] = info
@@ -722,7 +737,7 @@ type subster struct {
// args shapes. For a method with a generic receiver, it returns an instantiated
// function type where the receiver becomes the first parameter. For either a generic
// method or function, a dictionary parameter is the added as the very first
-// parameter. genericSubst fills in info.dictParam and info.tparamToBound.
+// parameter. genericSubst fills in info.dictParam and info.shapeToBound.
func (g *genInst) genericSubst(newsym *types.Sym, nameNode *ir.Name, shapes []*types.Type, isMethod bool, info *instInfo) *ir.Func {
var tparams []*types.Type
if isMethod {