aboutsummaryrefslogtreecommitdiff
path: root/test/typeparam
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2023-02-14 15:13:50 -0800
committerMatthew Dempsky <mdempsky@google.com>2023-02-27 23:07:49 +0000
commitfa9efd9171eac65321b02724d72a46cfb395ed52 (patch)
treea2b7a1484237bf5d755b696c1d4e1574a396c495 /test/typeparam
parent52af6550c92b1023e64c48e7b0fd947e539fb30f (diff)
downloadgo-fa9efd9171eac65321b02724d72a46cfb395ed52.tar.xz
cmd/compile/internal/noder: correct positions for synthetic closures
When inlining functions that contain function literals, we need to be careful about position information. The OCLOSURE node should use the inline-adjusted position, but the ODCLFUNC and its body should use the original positions. However, the same problem can arise with certain generic constructs, which require the compiler to synthesize function literals to insert dictionary arguments. go.dev/cl/425395 fixed the issue with user-written function literals in a somewhat kludgy way; this CL extends the same solution to synthetic function literals. This is all quite subtle and the solutions aren't terribly robust, so longer term it's probably desirable to revisit how we track inlining context for positions. But for now, this seems to be the least bad solution, esp. for backporting to 1.20. Updates #54625. Fixes #58513. Change-Id: Icc43a70dbb11a0e665cbc9e6a64ef274ad8253d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/468415 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Than McIntosh <thanm@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'test/typeparam')
-rw-r--r--test/typeparam/issue58513.go60
1 files changed, 60 insertions, 0 deletions
diff --git a/test/typeparam/issue58513.go b/test/typeparam/issue58513.go
new file mode 100644
index 0000000000..37cb5725ca
--- /dev/null
+++ b/test/typeparam/issue58513.go
@@ -0,0 +1,60 @@
+// run
+
+// Copyright 2023 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.
+
+// Some derived-type expressions require the compiler to synthesize
+// function literals to plumb sub-dictionaries appropriately.
+// However, when these expressions are inlined, we were constructing
+// the function literal bodies with the inline-adjusted positions
+// instead of the original (inline-free) positions, which could lead
+// to infinite loops when unwinding the stack.
+
+package main
+
+import "runtime"
+
+func assert[_ any]() {
+ panic(0)
+}
+
+func Assert[To any]() func() {
+ return assert[To]
+}
+
+type asserter[_ any] struct{}
+
+func (asserter[_]) assert() {
+ panic(0)
+}
+
+func AssertMV[To any]() func() {
+ return asserter[To]{}.assert
+}
+
+func AssertME[To any]() func(asserter[To]) {
+ return asserter[To].assert
+}
+
+var me = AssertME[string]()
+
+var tests = []func(){
+ Assert[int](),
+ AssertMV[int](),
+ func() { me(asserter[string]{}) },
+}
+
+func main() {
+ for _, test := range tests {
+ func() {
+ defer func() {
+ recover()
+
+ // Check that we can unwind the stack without infinite looping.
+ runtime.Caller(1000)
+ }()
+ test()
+ }()
+ }
+}