mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
cmd/compile: make sure that the names created for instantiated type are the same
Now we have two functions that create names for instantiated types. They are inconsistent when dealing with byte/rune type. This CL makes instTypeName2 reuse the code of typecheck.InstTypeName Fixes #48198 Change-Id: I4c216b532cba6618ef9b63fd0b76e8f1c0ed7a75 Reviewed-on: https://go-review.googlesource.com/c/go/+/347491 Reviewed-by: Dan Scales <danscales@google.com> Trust: Dan Scales <danscales@google.com> Trust: Keith Randall <khr@golang.org> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
a1938435d6
commit
6226020c2f
|
@ -5,7 +5,6 @@
|
|||
package noder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/ir"
|
||||
"cmd/compile/internal/typecheck"
|
||||
|
@ -72,29 +71,12 @@ func (g *irgen) typ1(typ types2.Type) *types.Type {
|
|||
|
||||
// instTypeName2 creates a name for an instantiated type, base on the type args
|
||||
// (given as types2 types).
|
||||
func instTypeName2(name string, targs *types2.TypeList) string {
|
||||
b := bytes.NewBufferString(name)
|
||||
b.WriteByte('[')
|
||||
n := targs.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
targ := targs.At(i)
|
||||
if i > 0 {
|
||||
b.WriteByte(',')
|
||||
}
|
||||
// Include package names for all types, including typeparams, to
|
||||
// make sure type arguments are uniquely specified.
|
||||
tname := types2.TypeString(targ,
|
||||
func(pkg *types2.Package) string { return pkg.Name() })
|
||||
if strings.Index(tname, ", ") >= 0 {
|
||||
// types2.TypeString puts spaces after a comma in a type
|
||||
// list, but we don't want spaces in our actual type names
|
||||
// and method/function names derived from them.
|
||||
tname = strings.Replace(tname, ", ", ",", -1)
|
||||
}
|
||||
b.WriteString(tname)
|
||||
func (g *irgen) instTypeName2(name string, targs *types2.TypeList) string {
|
||||
rparams := make([]*types.Type, targs.Len())
|
||||
for i := range rparams {
|
||||
rparams[i] = g.typ(targs.At(i))
|
||||
}
|
||||
b.WriteByte(']')
|
||||
return b.String()
|
||||
return typecheck.InstTypeName(name, rparams)
|
||||
}
|
||||
|
||||
// typ0 converts a types2.Type to a types.Type, but doesn't do the caching check
|
||||
|
@ -119,7 +101,7 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
|
|||
//
|
||||
// When converted to types.Type, typ has a unique name,
|
||||
// based on the names of the type arguments.
|
||||
instName := instTypeName2(typ.Obj().Name(), typ.TArgs())
|
||||
instName := g.instTypeName2(typ.Obj().Name(), typ.TArgs())
|
||||
s := g.pkg(typ.Obj().Pkg()).Lookup(instName)
|
||||
if s.Def != nil {
|
||||
// We have already encountered this instantiation.
|
||||
|
@ -314,7 +296,7 @@ func (g *irgen) fillinMethods(typ *types2.Named, ntyp *types.Type) {
|
|||
// generic type, so we have to do a substitution to get
|
||||
// the name/type of the method of the instantiated type,
|
||||
// using m.Type().RParams() and typ.TArgs()
|
||||
inst2 := instTypeName2("", typ.TArgs())
|
||||
inst2 := g.instTypeName2("", typ.TArgs())
|
||||
name := meth.Sym().Name
|
||||
i1 := strings.Index(name, "[")
|
||||
i2 := strings.Index(name[i1:], "]")
|
||||
|
|
22
test/typeparam/issue48198.go
Normal file
22
test/typeparam/issue48198.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
// compile -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 p
|
||||
|
||||
type Foo[T any] struct {
|
||||
}
|
||||
|
||||
func (foo Foo[T]) Get() {
|
||||
}
|
||||
|
||||
var(
|
||||
_ = Foo[byte]{}
|
||||
_ = Foo[[]byte]{}
|
||||
_ = Foo[map[byte]rune]{}
|
||||
|
||||
_ = Foo[rune]{}
|
||||
_ = Foo[[]rune]{}
|
||||
_ = Foo[map[rune]byte]{}
|
||||
)
|
Loading…
Reference in a new issue