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>
This commit is contained in:
Russ Cox 2022-11-15 09:54:39 -05:00
parent 56d1820782
commit b14cf3d93a
2 changed files with 9 additions and 2 deletions

View file

@ -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]
}

View file

@ -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