interp: fix type recursivity detection

Fix the logic to detect recursive struct types, which was giving a false positive.
We now use the local type name  as key in tracker map.

A non-regression test case is included (_test/struct49.go).

This completes #1008.
This commit is contained in:
Marc Vertes
2021-01-19 19:32:05 +01:00
committed by GitHub
parent 8fa00f826c
commit 274eecdf18
2 changed files with 45 additions and 3 deletions

41
_test/struct59.go Normal file
View File

@@ -0,0 +1,41 @@
package main
import (
"fmt"
)
type A struct {
B map[string]*B
C map[string]*C
}
type C struct {
D *D
E *E
}
type D struct {
F *F
G []G
}
type E struct {
H []H
F *F
}
type B struct{}
type F struct{}
type G struct{}
type H struct{}
func main() {
conf := &A{
B: make(map[string]*B),
C: make(map[string]*C),
}
fmt.Println(conf)
}
// Output:
// &{map[] map[]}

View File

@@ -1414,7 +1414,7 @@ func (t *itype) refType(defined map[string]*itype, wrapRecursive bool) reflect.T
t.rtype = reflect.TypeOf(new(error)).Elem()
case funcT:
if t.name != "" {
defined[name] = t
defined[name] = t // TODO(marc): make sure that key is name and not t.name.
}
variadic := false
in := make([]reflect.Type, len(t.arg))
@@ -1435,10 +1435,11 @@ func (t *itype) refType(defined map[string]*itype, wrapRecursive bool) reflect.T
t.rtype = reflect.PtrTo(t.val.refType(defined, wrapRecursive))
case structT:
if t.name != "" {
if defined[name] != nil {
// Check against local t.name and not name to catch recursive type definitions.
if defined[t.name] != nil {
recursive = true
}
defined[name] = t
defined[t.name] = t
}
var fields []reflect.StructField
// TODO(mpl): make Anonymous work for recursive types too. Maybe not worth the