Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion staticcheck/fakexml/typeinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,19 @@ var tinfoMap sync.Map // map[reflect.Type]*typeInfo
// getTypeInfo returns the typeInfo structure with details necessary
// for marshaling and unmarshaling typ.
func getTypeInfo(typ fakereflect.TypeAndCanAddr) (*typeInfo, error) {
return getTypeInfoRecursive(typ, map[fakereflect.TypeAndCanAddr]bool{})
}

func getTypeInfoRecursive(typ fakereflect.TypeAndCanAddr, visiting map[fakereflect.TypeAndCanAddr]bool) (*typeInfo, error) {
if ti, ok := tinfoMap.Load(typ); ok {
return ti.(*typeInfo), nil
}
if visiting[typ] {
// Recursive embedded structs cannot contribute fields indefinitely.
return &typeInfo{}, nil
}
visiting[typ] = true
defer delete(visiting, typ)

tinfo := &typeInfo{}
if typ.IsStruct() && !typeutil.IsTypeWithName(typ.Type, "encoding/xml.Name") {
Expand All @@ -95,7 +105,7 @@ func getTypeInfo(typ fakereflect.TypeAndCanAddr) (*typeInfo, error) {
t = t.Elem()
}
if t.IsStruct() {
inner, err := getTypeInfo(t)
inner, err := getTypeInfoRecursive(t, visiting)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ type Recursive struct {
Field *Recursive
}

type RecursiveEmbed struct {
*RecursiveEmbed
}

type ValueMarshaler chan int

func (ValueMarshaler) MarshalText() ([]byte, error) { return nil, nil }
Expand Down Expand Up @@ -316,6 +320,11 @@ func cyclicPointer() {
xml.Marshal(s) //@ diag(`cyclic type P, via x.Foo.Bar`)
}

func cyclicEmbeddedStruct() {
var value RecursiveEmbed
xml.Marshal(value)
}

func functionAsArgument(arg T1) {
// https://staticcheck.io/issues/1660

Expand Down