]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: fix re-export closure
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 10 Mar 2022 16:41:56 +0000 (23:41 +0700)
committerKeith Randall <khr@golang.org>
Fri, 11 Mar 2022 00:42:08 +0000 (00:42 +0000)
For hidden closure built during stenciling to implement a function
instantiation, the function may come from other package, not local
package, which causes the ICE for code that re-export the hidden closure
after inlining.

To fix it, use the closure package for export writer when writing out
the closure itself.

Fixes #51423

Change-Id: I23b067ba14e2d602a0fc3b2e99bd9317afbe53ff
Reviewed-on: https://go-review.googlesource.com/c/go/+/391574
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/typecheck/iexport.go
src/cmd/compile/internal/typecheck/iimport.go
test/typeparam/issue51423.dir/a.go [new file with mode: 0644]
test/typeparam/issue51423.dir/b.go [new file with mode: 0644]
test/typeparam/issue51423.go [new file with mode: 0644]

index fe0c80ac58413e9c3d6a1c59a420522ddc6f2490..341856ca46caa3d3a09151a99f1b0f306518900a 100644 (file)
@@ -1835,7 +1835,10 @@ func (w *exportWriter) expr(n ir.Node) {
                n := n.(*ir.ClosureExpr)
                w.op(ir.OCLOSURE)
                w.pos(n.Pos())
+               old := w.currPkg
+               w.setPkg(n.Type().Pkg(), true)
                w.signature(n.Type())
+               w.setPkg(old, true)
 
                // Write out id for the Outer of each conditional variable. The
                // conditional variable itself for this closure will be re-created
index ef91f550a5a1fe3460516a5ec70c69649e012966..28a50605aab444f8ef4c85eb3f155ac42a751271 100644 (file)
@@ -1374,7 +1374,9 @@ func (r *importReader) node() ir.Node {
        case ir.OCLOSURE:
                //println("Importing CLOSURE")
                pos := r.pos()
+               r.setPkg()
                typ := r.signature(nil, nil)
+               r.setPkg()
 
                // All the remaining code below is similar to (*noder).funcLit(), but
                // with Dcls and ClosureVars lists already set up
diff --git a/test/typeparam/issue51423.dir/a.go b/test/typeparam/issue51423.dir/a.go
new file mode 100644 (file)
index 0000000..e824d0e
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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
+
+type Comparator[T any] func(v1, v2 T) int
+
+func CompareInt[T ~int](a, b T) int {
+       if a < b {
+               return -1
+       }
+       if a == b {
+               return 0
+       }
+       return 1
+}
diff --git a/test/typeparam/issue51423.dir/b.go b/test/typeparam/issue51423.dir/b.go
new file mode 100644 (file)
index 0000000..2bad19f
--- /dev/null
@@ -0,0 +1,11 @@
+package b
+
+import "./a"
+
+func C() a.Comparator[int] {
+       return a.CompareInt[int]
+}
+
+func main() {
+       _ = C()(1, 2)
+}
diff --git a/test/typeparam/issue51423.go b/test/typeparam/issue51423.go
new file mode 100644 (file)
index 0000000..8bb5c3e
--- /dev/null
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2022 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