fix: emulate struct by interface{} only for recursive struct types
This commit is contained in:
committed by
Traefiker Bot
parent
7a0c09f5eb
commit
4f93be7f19
19
_test/struct29.go
Normal file
19
_test/struct29.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
type T1 struct {
|
||||
A []T2
|
||||
B []T2
|
||||
}
|
||||
|
||||
type T2 struct {
|
||||
name string
|
||||
}
|
||||
|
||||
var t = T1{}
|
||||
|
||||
func main() {
|
||||
println("ok")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// ok
|
||||
19
_test/struct30.go
Normal file
19
_test/struct30.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
type T1 struct {
|
||||
A []T2
|
||||
M map[uint64]T2
|
||||
}
|
||||
|
||||
type T2 struct {
|
||||
name string
|
||||
}
|
||||
|
||||
var t = T1{}
|
||||
|
||||
func main() {
|
||||
println("ok")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// ok
|
||||
@@ -30,6 +30,7 @@ func (interp *Interpreter) gta(root *node, rpath string) ([]*node, error) {
|
||||
case defineStmt:
|
||||
var atyp *itype
|
||||
if n.nleft+n.nright < len(n.child) {
|
||||
// Type is declared explicitly in the assign expression.
|
||||
if atyp, err = nodeType(interp, sc, n.child[n.nleft]); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ func isRecursiveStruct(t *itype, rtype reflect.Type) bool {
|
||||
if t.cat == structT && rtype.Kind() == reflect.Interface {
|
||||
return true
|
||||
}
|
||||
if t.cat == ptrT {
|
||||
if t.cat == ptrT && t.rtype != nil {
|
||||
return isRecursiveStruct(t.val, t.rtype.Elem())
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -885,7 +885,9 @@ func (t *itype) refType(defined map[string]bool) reflect.Type {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if t.val != nil && defined[t.val.name] {
|
||||
if t.val != nil && defined[t.val.name] && !t.val.incomplete && t.val.rtype == nil {
|
||||
// Replace reference to self (direct or indirect) by an interface{} to handle
|
||||
// recursive types with reflect.
|
||||
t.val.rtype = interf
|
||||
}
|
||||
switch t.cat {
|
||||
|
||||
Reference in New Issue
Block a user