]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: make sure that the names created for instantiated type are the same
authorkorzhao <korzhao95@gmail.com>
Mon, 6 Sep 2021 13:08:05 +0000 (21:08 +0800)
committerDan Scales <danscales@google.com>
Tue, 7 Sep 2021 03:56:13 +0000 (03:56 +0000)
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>

src/cmd/compile/internal/noder/types.go
test/typeparam/issue48198.go [new file with mode: 0644]

index c549dffc461bf11064cbdbaa8ed9bcc9978911be..b70d8d198e3d6813f9af67277868e714468fd338 100644 (file)
@@ -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 (file)
index 0000000..1d7e44e
--- /dev/null
@@ -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]{}
+)