aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2022-11-15 09:54:39 -0500
committerMichael Pratt <mpratt@google.com>2022-12-09 20:56:57 +0000
commitdf5d4d3daab7e022335c0f3304d7b750bdd731a0 (patch)
tree55552617fb140fbd9d855c3593133a14f159dd90
parent741e65d2bd02011fa8ba81e13f0f3d3df4f4f087 (diff)
downloadgo-df5d4d3daab7e022335c0f3304d7b750bdd731a0.tar.gz
go-df5d4d3daab7e022335c0f3304d7b750bdd731a0.zip
[release-branch.go1.19] sync/atomic: allow linked list of atomic pointers again
For #56603, CL 448275 added a _ [0]T field to atomic.Pointer, so that different kinds of atomic.Pointer are not convertible. Unfortunately, that breaks code like: type List struct { Next atomic.Pointer[List] } which should be valid, just as using Next *List is valid. Instead, we get: ./atomic_test.go:2533:6: invalid recursive type List ./atomic_test.go:2533:6: List refers to ./atomic_test.go:2534:13: "sync/atomic".Pointer refers to ./atomic_test.go:2533:6: List Fix by using _[0]*T instead. For #56638. Fixes #57124. Change-Id: Icc4c83c691d35961d20cb14b824223d6c779ac5e Reviewed-on: https://go-review.googlesource.com/c/go/+/450655 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> (cherry picked from commit b14cf3d93ae5c477dd35f13f6ba41044f01a7f7d) Reviewed-on: https://go-review.googlesource.com/c/go/+/452438 Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
-rw-r--r--src/sync/atomic/atomic_test.go6
-rw-r--r--src/sync/atomic/type.go5
2 files changed, 9 insertions, 2 deletions
diff --git a/src/sync/atomic/atomic_test.go b/src/sync/atomic/atomic_test.go
index 02d55fbc19..3ab5e836e9 100644
--- a/src/sync/atomic/atomic_test.go
+++ b/src/sync/atomic/atomic_test.go
@@ -2605,3 +2605,9 @@ func TestNilDeref(t *testing.T) {
}()
}
}
+
+// Test that this compiles.
+// When atomic.Pointer used _ [0]T, it did not.
+type List struct {
+ Next Pointer[List]
+}
diff --git a/src/sync/atomic/type.go b/src/sync/atomic/type.go
index 2d1e621652..93058ca38d 100644
--- a/src/sync/atomic/type.go
+++ b/src/sync/atomic/type.go
@@ -37,9 +37,10 @@ func b32(b bool) uint32 {
// A Pointer is an atomic pointer of type *T. The zero value is a nil *T.
type Pointer[T any] struct {
- // Mention T in a field to disallow conversion between Pointer types.
+ // Mention *T in a field to disallow conversion between Pointer types.
// See go.dev/issue/56603 for more details.
- _ [0]T
+ // Use *T, not T, to avoid spurious recursive type definition errors.
+ _ [0]*T
_ noCopy
v unsafe.Pointer