types/ptr: deprecate ptr.To, use Go 1.26 new
Updates #18682 Change-Id: I62f6aa0de2a15ef8c1435032c6aa74a181c25f8f Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
8cfbaa717d
commit
2a64c03c95
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/go-json-experiment/json"
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
@@ -72,7 +71,7 @@ func TestInterfaceCoders(t *testing.T) {
|
||||
wantJSON: `{"Foo":"hello"}`,
|
||||
}, {
|
||||
label: "BarPointer",
|
||||
wantVal: InterfaceWrapper{ptr.To(Bar(5))},
|
||||
wantVal: InterfaceWrapper{new(Bar(5))},
|
||||
wantJSON: `{"Bar":5}`,
|
||||
}, {
|
||||
label: "BarValue",
|
||||
|
||||
@@ -6,8 +6,6 @@ package lazy
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// DeferredInit allows one or more funcs to be deferred
|
||||
@@ -91,7 +89,7 @@ func (d *DeferredInit) doSlow() (err *error) {
|
||||
}()
|
||||
for _, f := range d.funcs {
|
||||
if err := f(); err != nil {
|
||||
return ptr.To(err)
|
||||
return new(err)
|
||||
}
|
||||
}
|
||||
return nilErrPtr
|
||||
|
||||
+3
-5
@@ -7,13 +7,11 @@ package lazy
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// nilErrPtr is a sentinel *error value for SyncValue.err to signal
|
||||
// that SyncValue.v is valid.
|
||||
var nilErrPtr = ptr.To[error](nil)
|
||||
var nilErrPtr = new(error(nil))
|
||||
|
||||
// SyncValue is a lazily computed value.
|
||||
//
|
||||
@@ -80,7 +78,7 @@ func (z *SyncValue[T]) GetErr(fill func() (T, error)) (T, error) {
|
||||
|
||||
// Update z.err after z.v; see field docs.
|
||||
if err != nil {
|
||||
z.err.Store(ptr.To(err))
|
||||
z.err.Store(new(err))
|
||||
} else {
|
||||
z.err.Store(nilErrPtr)
|
||||
}
|
||||
@@ -145,7 +143,7 @@ func (z *SyncValue[T]) SetForTest(tb testing_TB, val T, err error) {
|
||||
|
||||
z.v = val
|
||||
if err != nil {
|
||||
z.err.Store(ptr.To(err))
|
||||
z.err.Store(new(err))
|
||||
} else {
|
||||
z.err.Store(nilErrPtr)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"time"
|
||||
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// NodeMutation is the common interface for types that describe
|
||||
@@ -55,7 +54,7 @@ type NodeMutationOnline struct {
|
||||
}
|
||||
|
||||
func (m NodeMutationOnline) Apply(n *tailcfg.Node) {
|
||||
n.Online = ptr.To(m.Online)
|
||||
n.Online = new(m.Online)
|
||||
}
|
||||
|
||||
// NodeMutationLastSeen is a NodeMutation that says a node's LastSeen
|
||||
@@ -66,14 +65,14 @@ type NodeMutationLastSeen struct {
|
||||
}
|
||||
|
||||
func (m NodeMutationLastSeen) Apply(n *tailcfg.Node) {
|
||||
n.LastSeen = ptr.To(m.LastSeen)
|
||||
n.LastSeen = new(m.LastSeen)
|
||||
}
|
||||
|
||||
var peerChangeFields = sync.OnceValue(func() []reflect.StructField {
|
||||
var fields []reflect.StructField
|
||||
rt := reflect.TypeFor[tailcfg.PeerChange]()
|
||||
for i := range rt.NumField() {
|
||||
fields = append(fields, rt.Field(i))
|
||||
for field := range rt.Fields() {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
return fields
|
||||
})
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// tests mapResponseContainsNonPatchFields
|
||||
@@ -117,7 +116,7 @@ func TestMutationsFromMapResponse(t *testing.T) {
|
||||
name: "patch-online",
|
||||
mr: fromChanges(&tailcfg.PeerChange{
|
||||
NodeID: 1,
|
||||
Online: ptr.To(true),
|
||||
Online: new(true),
|
||||
}),
|
||||
want: muts(NodeMutationOnline{1, true}),
|
||||
},
|
||||
@@ -125,7 +124,7 @@ func TestMutationsFromMapResponse(t *testing.T) {
|
||||
name: "patch-online-false",
|
||||
mr: fromChanges(&tailcfg.PeerChange{
|
||||
NodeID: 1,
|
||||
Online: ptr.To(false),
|
||||
Online: new(false),
|
||||
}),
|
||||
want: muts(NodeMutationOnline{1, false}),
|
||||
},
|
||||
@@ -133,7 +132,7 @@ func TestMutationsFromMapResponse(t *testing.T) {
|
||||
name: "patch-lastseen",
|
||||
mr: fromChanges(&tailcfg.PeerChange{
|
||||
NodeID: 1,
|
||||
LastSeen: ptr.To(time.Unix(12345, 0)),
|
||||
LastSeen: new(time.Unix(12345, 0)),
|
||||
}),
|
||||
want: muts(NodeMutationLastSeen{1, time.Unix(12345, 0)}),
|
||||
},
|
||||
|
||||
+1
-2
@@ -9,7 +9,6 @@ import (
|
||||
jsonv2 "github.com/go-json-experiment/json"
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/types/views"
|
||||
"tailscale.com/util/must"
|
||||
)
|
||||
@@ -47,7 +46,7 @@ func (i *Item[T]) SetManagedValue(val T) {
|
||||
// It is a runtime error to call [Item.Clone] if T contains pointers
|
||||
// but does not implement [views.Cloner].
|
||||
func (i Item[T]) Clone() *Item[T] {
|
||||
res := ptr.To(i)
|
||||
res := new(i)
|
||||
if v, ok := i.ValueOk(); ok {
|
||||
res.s.Value.Set(must.Get(deepClone(v)))
|
||||
}
|
||||
|
||||
+1
-2
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"golang.org/x/exp/constraints"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/types/views"
|
||||
)
|
||||
|
||||
@@ -62,7 +61,7 @@ func (ls *List[T]) View() ListView[T] {
|
||||
|
||||
// Clone returns a copy of l that aliases no memory with l.
|
||||
func (ls List[T]) Clone() *List[T] {
|
||||
res := ptr.To(ls)
|
||||
res := new(ls)
|
||||
if v, ok := ls.s.Value.GetOk(); ok {
|
||||
res.s.Value.Set(append(v[:0:0], v...))
|
||||
}
|
||||
|
||||
+1
-2
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"golang.org/x/exp/constraints"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/types/views"
|
||||
)
|
||||
|
||||
@@ -44,7 +43,7 @@ func (m *Map[K, V]) View() MapView[K, V] {
|
||||
|
||||
// Clone returns a copy of m that aliases no memory with m.
|
||||
func (m Map[K, V]) Clone() *Map[K, V] {
|
||||
res := ptr.To(m)
|
||||
res := new(m)
|
||||
if v, ok := m.s.Value.GetOk(); ok {
|
||||
res.s.Value.Set(maps.Clone(v))
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ package prefs
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// Clone makes a deep copy of TestPrefs.
|
||||
@@ -67,7 +65,7 @@ func (src *TestBundle) Clone() *TestBundle {
|
||||
dst := new(TestBundle)
|
||||
*dst = *src
|
||||
if dst.Nested != nil {
|
||||
dst.Nested = ptr.To(*src.Nested)
|
||||
dst.Nested = new(*src.Nested)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
jsonv2 "github.com/go-json-experiment/json"
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/types/views"
|
||||
)
|
||||
|
||||
@@ -45,7 +44,7 @@ func (ls *StructList[T]) SetManagedValue(val []T) {
|
||||
|
||||
// Clone returns a copy of l that aliases no memory with l.
|
||||
func (ls StructList[T]) Clone() *StructList[T] {
|
||||
res := ptr.To(ls)
|
||||
res := new(ls)
|
||||
if v, ok := ls.s.Value.GetOk(); ok {
|
||||
res.s.Value.Set(deepCloneSlice(v))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
jsonv2 "github.com/go-json-experiment/json"
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/types/views"
|
||||
)
|
||||
|
||||
@@ -43,7 +42,7 @@ func (m *StructMap[K, V]) SetManagedValue(val map[K]V) {
|
||||
|
||||
// Clone returns a copy of m that aliases no memory with m.
|
||||
func (m StructMap[K, V]) Clone() *StructMap[K, V] {
|
||||
res := ptr.To(m)
|
||||
res := new(m)
|
||||
if v, ok := m.s.Value.GetOk(); ok {
|
||||
res.s.Value.Set(deepCloneMap(v))
|
||||
}
|
||||
|
||||
+10
-1
@@ -2,9 +2,18 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package ptr contains the ptr.To function.
|
||||
//
|
||||
// Deprecated: Use Go 1.26's new(value) expression instead.
|
||||
// See https://go.dev/doc/go1.26#language.
|
||||
package ptr
|
||||
|
||||
// To returns a pointer to a shallow copy of v.
|
||||
//
|
||||
// Deprecated: Use Go 1.26's new(value) expression instead.
|
||||
// For example, ptr.To(42) can be written as new(42).
|
||||
// See https://go.dev/doc/go1.26#language.
|
||||
//
|
||||
//go:fix inline
|
||||
func To[T any](v T) *T {
|
||||
return &v
|
||||
return new(v)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
jsonv2 "github.com/go-json-experiment/json"
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
"go4.org/mem"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// ByteSlice is a read-only accessor for types that are backed by a []byte.
|
||||
@@ -901,7 +900,7 @@ func (p ValuePointer[T]) Clone() *T {
|
||||
if p.ж == nil {
|
||||
return nil
|
||||
}
|
||||
return ptr.To(*p.ж)
|
||||
return new(*p.ж)
|
||||
}
|
||||
|
||||
// String implements [fmt.Stringer].
|
||||
|
||||
Reference in New Issue
Block a user