mirror of
https://github.com/golang/go
synced 2024-11-11 20:20:23 -07:00
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>
This commit is contained in:
parent
67917c3d78
commit
5b9207ff67
@ -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 {
|
||||
|
22
test/typeparam/issue50121.dir/a.go
Normal file
22
test/typeparam/issue50121.dir/a.go
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package a
|
||||
|
||||
import (
|
||||
"constraints"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type Builder[T constraints.Integer] struct{}
|
||||
|
||||
func (r Builder[T]) New() T {
|
||||
return T(rand.Int())
|
||||
}
|
||||
|
||||
var IntBuilder = Builder[int]{}
|
||||
|
||||
func BuildInt() int {
|
||||
return IntBuilder.New()
|
||||
}
|
18
test/typeparam/issue50121.dir/main.go
Normal file
18
test/typeparam/issue50121.dir/main.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"a"
|
||||
)
|
||||
|
||||
//go:noinline
|
||||
func BuildInt() int {
|
||||
return a.BuildInt()
|
||||
}
|
||||
|
||||
func main() {
|
||||
BuildInt()
|
||||
}
|
7
test/typeparam/issue50121.go
Normal file
7
test/typeparam/issue50121.go
Normal file
@ -0,0 +1,7 @@
|
||||
// rundir -G=3
|
||||
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ignored
|
Loading…
Reference in New Issue
Block a user