From b14cf3d93ae5c477dd35f13f6ba41044f01a7f7d Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 15 Nov 2022 09:54:39 -0500 Subject: [PATCH] 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 TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek --- src/sync/atomic/atomic_test.go | 6 ++++++ 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 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 -- 2.48.1