]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't do Resolve on OKEY identifiers during import
authorDan Scales <danscales@google.com>
Wed, 10 Nov 2021 19:39:18 +0000 (11:39 -0800)
committerDan Scales <danscales@google.com>
Wed, 10 Nov 2021 21:53:03 +0000 (21:53 +0000)
For generic functions, we can export untransformed OKEY nodes, and the
key identifier is written as an ONONAME. But in this case, we do not
want to call Resolve() on the identifier, since we may resolve to a
global type (as happens in this issue) or other global symbol with the
same name, if it exists. We just want to keep the key identifier as an
Ident node.

To solve this, I added an extra bool when exporting an ONONAME entry,
which indicates if this entry is for a key or for a global (external)
symbol. When the bool is true (this is for a key), we avoid calling
Resolve().

Fixes #49497

Change-Id: Ic8fa93d37bcad2110e0e0d060080b733e07e35d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/363074
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/typecheck/iexport.go
src/cmd/compile/internal/typecheck/iimport.go
test/typeparam/issue49497.dir/a.go [new file with mode: 0644]
test/typeparam/issue49497.dir/main.go [new file with mode: 0644]
test/typeparam/issue49497.go [new file with mode: 0644]

index f685851e40c370031339827b04b3cea345d341e9..bf12ba803b7f4803e4718c9f6ee7e6b5b8b0332f 100644 (file)
@@ -1735,6 +1735,8 @@ func (w *exportWriter) expr(n ir.Node) {
                n := n.(*ir.Name)
                if (n.Class == ir.PEXTERN || n.Class == ir.PFUNC) && !ir.IsBlank(n) {
                        w.op(ir.ONONAME)
+                       // Indicate that this is not an OKEY entry.
+                       w.bool(false)
                        w.qualifiedIdent(n)
                        if go117ExportTypes {
                                w.typ(n.Type())
@@ -1761,7 +1763,9 @@ func (w *exportWriter) expr(n ir.Node) {
 
        case ir.ONONAME:
                w.op(ir.ONONAME)
-               // This should only be for OKEY nodes in generic functions
+               // This can only be for OKEY nodes in generic functions. Mark it
+               // as a key entry.
+               w.bool(true)
                s := n.Sym()
                w.string(s.Name)
                w.pkg(s.Pkg)
index 26bc838ed99f8293679f3d3d452b175ac8ca4740..09f87df5803eec2bfac3b2c1c00b1947a6ff3d59 100644 (file)
@@ -1315,9 +1315,15 @@ func (r *importReader) node() ir.Node {
                return n
 
        case ir.ONONAME:
+               isKey := r.bool()
                n := r.qualifiedIdent()
                if go117ExportTypes {
-                       n2 := Resolve(n)
+                       var n2 ir.Node = n
+                       // Key ONONAME entries should not be resolved - they should
+                       // stay as identifiers.
+                       if !isKey {
+                               n2 = Resolve(n)
+                       }
                        typ := r.typ()
                        if n2.Type() == nil {
                                n2.SetType(typ)
diff --git a/test/typeparam/issue49497.dir/a.go b/test/typeparam/issue49497.dir/a.go
new file mode 100644 (file)
index 0000000..86062d4
--- /dev/null
@@ -0,0 +1,26 @@
+// 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
+
+func F[T any]() A[T] {
+       var x A[T]
+       return x
+}
+
+type A[T any] struct {
+       b B[T]
+}
+
+func (a A[T]) M() C[T] {
+       return C[T]{
+               B: a.b,
+       }
+}
+
+type B[T any] struct{}
+
+type C[T any] struct {
+       B B[T]
+}
diff --git a/test/typeparam/issue49497.dir/main.go b/test/typeparam/issue49497.dir/main.go
new file mode 100644 (file)
index 0000000..3725e55
--- /dev/null
@@ -0,0 +1,11 @@
+// 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"
+
+func main() {
+       a.F[string]()
+}
diff --git a/test/typeparam/issue49497.go b/test/typeparam/issue49497.go
new file mode 100644 (file)
index 0000000..76930e5
--- /dev/null
@@ -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