mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
cmd/cloner, cmd/viewer, util/codegen: add support for aliases of cloneable types
We have several checked type assertions to *types.Named in both cmd/cloner and cmd/viewer. As Go 1.23 updates the go/types package to produce Alias type nodes for type aliases, these type assertions no longer work as expected unless the new behavior is disabled with gotypesalias=0. In this PR, we add codegen.NamedTypeOf(t types.Type), which functions like t.(*types.Named) but also unrolls type aliases. We then use it in place of type assertions in the cmd/cloner and cmd/viewer packages where appropriate. We also update type switches to include *types.Alias alongside *types.Named in relevant cases, remove *types.Struct cases when switching on types.Type.Underlying and update the tests with more cases where type aliases can be used. Updates #13224 Updates #12912 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
@@ -204,13 +204,27 @@ type StructWithContainers struct {
|
||||
}
|
||||
|
||||
type (
|
||||
StructWithPtrsAlias = StructWithPtrs
|
||||
StructWithoutPtrsAlias = StructWithoutPtrs
|
||||
StructWithPtrsAlias = StructWithPtrs
|
||||
StructWithoutPtrsAlias = StructWithoutPtrs
|
||||
StructWithPtrsAliasView = StructWithPtrsView
|
||||
StructWithoutPtrsAliasView = StructWithoutPtrsView
|
||||
)
|
||||
|
||||
type StructWithTypeAliasFields struct {
|
||||
WithPtr StructWithPtrsAlias
|
||||
WithoutPtr StructWithoutPtrsAlias
|
||||
|
||||
WithPtrByPtr *StructWithPtrsAlias
|
||||
WithoutPtrByPtr *StructWithoutPtrsAlias
|
||||
|
||||
SliceWithPtrs []*StructWithPtrsAlias
|
||||
SliceWithoutPtrs []*StructWithoutPtrsAlias
|
||||
|
||||
MapWithPtrs map[string]*StructWithPtrsAlias
|
||||
MapWithoutPtrs map[string]*StructWithoutPtrsAlias
|
||||
|
||||
MapOfSlicesWithPtrs map[string][]*StructWithPtrsAlias
|
||||
MapOfSlicesWithoutPtrs map[string][]*StructWithoutPtrsAlias
|
||||
}
|
||||
|
||||
type integer = constraints.Integer
|
||||
|
@@ -450,14 +450,78 @@ func (src *StructWithTypeAliasFields) Clone() *StructWithTypeAliasFields {
|
||||
}
|
||||
dst := new(StructWithTypeAliasFields)
|
||||
*dst = *src
|
||||
panic("TODO: WithPtr (*types.Struct)")
|
||||
dst.WithPtr = *src.WithPtr.Clone()
|
||||
dst.WithPtrByPtr = src.WithPtrByPtr.Clone()
|
||||
if dst.WithoutPtrByPtr != nil {
|
||||
dst.WithoutPtrByPtr = ptr.To(*src.WithoutPtrByPtr)
|
||||
}
|
||||
if src.SliceWithPtrs != nil {
|
||||
dst.SliceWithPtrs = make([]*StructWithPtrsAlias, len(src.SliceWithPtrs))
|
||||
for i := range dst.SliceWithPtrs {
|
||||
if src.SliceWithPtrs[i] == nil {
|
||||
dst.SliceWithPtrs[i] = nil
|
||||
} else {
|
||||
dst.SliceWithPtrs[i] = src.SliceWithPtrs[i].Clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
if src.SliceWithoutPtrs != nil {
|
||||
dst.SliceWithoutPtrs = make([]*StructWithoutPtrsAlias, len(src.SliceWithoutPtrs))
|
||||
for i := range dst.SliceWithoutPtrs {
|
||||
if src.SliceWithoutPtrs[i] == nil {
|
||||
dst.SliceWithoutPtrs[i] = nil
|
||||
} else {
|
||||
dst.SliceWithoutPtrs[i] = ptr.To(*src.SliceWithoutPtrs[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if dst.MapWithPtrs != nil {
|
||||
dst.MapWithPtrs = map[string]*StructWithPtrsAlias{}
|
||||
for k, v := range src.MapWithPtrs {
|
||||
if v == nil {
|
||||
dst.MapWithPtrs[k] = nil
|
||||
} else {
|
||||
dst.MapWithPtrs[k] = v.Clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
if dst.MapWithoutPtrs != nil {
|
||||
dst.MapWithoutPtrs = map[string]*StructWithoutPtrsAlias{}
|
||||
for k, v := range src.MapWithoutPtrs {
|
||||
if v == nil {
|
||||
dst.MapWithoutPtrs[k] = nil
|
||||
} else {
|
||||
dst.MapWithoutPtrs[k] = ptr.To(*v)
|
||||
}
|
||||
}
|
||||
}
|
||||
if dst.MapOfSlicesWithPtrs != nil {
|
||||
dst.MapOfSlicesWithPtrs = map[string][]*StructWithPtrsAlias{}
|
||||
for k := range src.MapOfSlicesWithPtrs {
|
||||
dst.MapOfSlicesWithPtrs[k] = append([]*StructWithPtrsAlias{}, src.MapOfSlicesWithPtrs[k]...)
|
||||
}
|
||||
}
|
||||
if dst.MapOfSlicesWithoutPtrs != nil {
|
||||
dst.MapOfSlicesWithoutPtrs = map[string][]*StructWithoutPtrsAlias{}
|
||||
for k := range src.MapOfSlicesWithoutPtrs {
|
||||
dst.MapOfSlicesWithoutPtrs[k] = append([]*StructWithoutPtrsAlias{}, src.MapOfSlicesWithoutPtrs[k]...)
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _StructWithTypeAliasFieldsCloneNeedsRegeneration = StructWithTypeAliasFields(struct {
|
||||
WithPtr StructWithPtrsAlias
|
||||
WithoutPtr StructWithoutPtrsAlias
|
||||
WithPtr StructWithPtrsAlias
|
||||
WithoutPtr StructWithoutPtrsAlias
|
||||
WithPtrByPtr *StructWithPtrsAlias
|
||||
WithoutPtrByPtr *StructWithoutPtrsAlias
|
||||
SliceWithPtrs []*StructWithPtrsAlias
|
||||
SliceWithoutPtrs []*StructWithoutPtrsAlias
|
||||
MapWithPtrs map[string]*StructWithPtrsAlias
|
||||
MapWithoutPtrs map[string]*StructWithoutPtrsAlias
|
||||
MapOfSlicesWithPtrs map[string][]*StructWithPtrsAlias
|
||||
MapOfSlicesWithoutPtrs map[string][]*StructWithoutPtrsAlias
|
||||
}{})
|
||||
|
||||
// Clone makes a deep copy of GenericTypeAliasStruct.
|
||||
|
@@ -724,11 +724,60 @@ func (v *StructWithTypeAliasFieldsView) UnmarshalJSON(b []byte) error {
|
||||
|
||||
func (v StructWithTypeAliasFieldsView) WithPtr() StructWithPtrsView { return v.ж.WithPtr.View() }
|
||||
func (v StructWithTypeAliasFieldsView) WithoutPtr() StructWithoutPtrsAlias { return v.ж.WithoutPtr }
|
||||
func (v StructWithTypeAliasFieldsView) WithPtrByPtr() StructWithPtrsAliasView {
|
||||
return v.ж.WithPtrByPtr.View()
|
||||
}
|
||||
func (v StructWithTypeAliasFieldsView) WithoutPtrByPtr() *StructWithoutPtrsAlias {
|
||||
if v.ж.WithoutPtrByPtr == nil {
|
||||
return nil
|
||||
}
|
||||
x := *v.ж.WithoutPtrByPtr
|
||||
return &x
|
||||
}
|
||||
|
||||
func (v StructWithTypeAliasFieldsView) SliceWithPtrs() views.SliceView[*StructWithPtrsAlias, StructWithPtrsAliasView] {
|
||||
return views.SliceOfViews[*StructWithPtrsAlias, StructWithPtrsAliasView](v.ж.SliceWithPtrs)
|
||||
}
|
||||
func (v StructWithTypeAliasFieldsView) SliceWithoutPtrs() views.SliceView[*StructWithoutPtrsAlias, StructWithoutPtrsAliasView] {
|
||||
return views.SliceOfViews[*StructWithoutPtrsAlias, StructWithoutPtrsAliasView](v.ж.SliceWithoutPtrs)
|
||||
}
|
||||
|
||||
func (v StructWithTypeAliasFieldsView) MapWithPtrs() views.MapFn[string, *StructWithPtrsAlias, StructWithPtrsAliasView] {
|
||||
return views.MapFnOf(v.ж.MapWithPtrs, func(t *StructWithPtrsAlias) StructWithPtrsAliasView {
|
||||
return t.View()
|
||||
})
|
||||
}
|
||||
|
||||
func (v StructWithTypeAliasFieldsView) MapWithoutPtrs() views.MapFn[string, *StructWithoutPtrsAlias, StructWithoutPtrsAliasView] {
|
||||
return views.MapFnOf(v.ж.MapWithoutPtrs, func(t *StructWithoutPtrsAlias) StructWithoutPtrsAliasView {
|
||||
return t.View()
|
||||
})
|
||||
}
|
||||
|
||||
func (v StructWithTypeAliasFieldsView) MapOfSlicesWithPtrs() views.MapFn[string, []*StructWithPtrsAlias, views.SliceView[*StructWithPtrsAlias, StructWithPtrsAliasView]] {
|
||||
return views.MapFnOf(v.ж.MapOfSlicesWithPtrs, func(t []*StructWithPtrsAlias) views.SliceView[*StructWithPtrsAlias, StructWithPtrsAliasView] {
|
||||
return views.SliceOfViews[*StructWithPtrsAlias, StructWithPtrsAliasView](t)
|
||||
})
|
||||
}
|
||||
|
||||
func (v StructWithTypeAliasFieldsView) MapOfSlicesWithoutPtrs() views.MapFn[string, []*StructWithoutPtrsAlias, views.SliceView[*StructWithoutPtrsAlias, StructWithoutPtrsAliasView]] {
|
||||
return views.MapFnOf(v.ж.MapOfSlicesWithoutPtrs, func(t []*StructWithoutPtrsAlias) views.SliceView[*StructWithoutPtrsAlias, StructWithoutPtrsAliasView] {
|
||||
return views.SliceOfViews[*StructWithoutPtrsAlias, StructWithoutPtrsAliasView](t)
|
||||
})
|
||||
}
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _StructWithTypeAliasFieldsViewNeedsRegeneration = StructWithTypeAliasFields(struct {
|
||||
WithPtr StructWithPtrsAlias
|
||||
WithoutPtr StructWithoutPtrsAlias
|
||||
WithPtr StructWithPtrsAlias
|
||||
WithoutPtr StructWithoutPtrsAlias
|
||||
WithPtrByPtr *StructWithPtrsAlias
|
||||
WithoutPtrByPtr *StructWithoutPtrsAlias
|
||||
SliceWithPtrs []*StructWithPtrsAlias
|
||||
SliceWithoutPtrs []*StructWithoutPtrsAlias
|
||||
MapWithPtrs map[string]*StructWithPtrsAlias
|
||||
MapWithoutPtrs map[string]*StructWithoutPtrsAlias
|
||||
MapOfSlicesWithPtrs map[string][]*StructWithPtrsAlias
|
||||
MapOfSlicesWithoutPtrs map[string][]*StructWithoutPtrsAlias
|
||||
}{})
|
||||
|
||||
// View returns a readonly view of GenericTypeAliasStruct.
|
||||
|
Reference in New Issue
Block a user