From: korzhao Date: Mon, 6 Sep 2021 13:08:05 +0000 (+0800) Subject: cmd/compile: make sure that the names created for instantiated type are the same X-Git-Tag: go1.18beta1~1467 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6226020c2f713e4545c73d56dc05676b642c9bc7;p=gostls13.git 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 Trust: Dan Scales Trust: Keith Randall Run-TryBot: Dan Scales TryBot-Result: Go Bot --- diff --git a/src/cmd/compile/internal/noder/types.go b/src/cmd/compile/internal/noder/types.go index c549dffc46..b70d8d198e 100644 --- a/src/cmd/compile/internal/noder/types.go +++ b/src/cmd/compile/internal/noder/types.go @@ -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:], "]") diff --git a/test/typeparam/issue48198.go b/test/typeparam/issue48198.go new file mode 100644 index 0000000000..1d7e44e0c4 --- /dev/null +++ b/test/typeparam/issue48198.go @@ -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]{} +)