aboutsummaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2022-11-15 09:54:39 -0500
committerRuss Cox <rsc@golang.org>2022-11-15 18:14:39 +0000
commitb14cf3d93ae5c477dd35f13f6ba41044f01a7f7d (patch)
treedb7a421a387b59923ef3f6f0412809007bcf6492 /src/sync
parent56d18207823d6e1c18ca46409180c40ae800230c (diff)
downloadgo-b14cf3d93ae5c477dd35f13f6ba41044f01a7f7d.tar.gz
go-b14cf3d93ae5c477dd35f13f6ba41044f01a7f7d.zip
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. 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>
Diffstat (limited to 'src/sync')
-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 0cc9b06a6c..c3604ef0af 100644
--- a/src/sync/atomic/atomic_test.go
+++ b/src/sync/atomic/atomic_test.go
@@ -2526,3 +2526,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 4d466232f1..cc016833d1 100644
--- a/src/sync/atomic/type.go
+++ b/src/sync/atomic/type.go
@@ -41,9 +41,10 @@ var _ = &Pointer[int]{}
// 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