diff options
author | Russ Cox <rsc@golang.org> | 2022-11-15 09:54:39 -0500 |
---|---|---|
committer | Michael Pratt <mpratt@google.com> | 2022-12-09 20:56:57 +0000 |
commit | df5d4d3daab7e022335c0f3304d7b750bdd731a0 (patch) | |
tree | 55552617fb140fbd9d855c3593133a14f159dd90 | |
parent | 741e65d2bd02011fa8ba81e13f0f3d3df4f4f087 (diff) | |
download | go-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.go | 6 | ||||
-rw-r--r-- | src/sync/atomic/type.go | 5 |
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 |