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:
|
case defineStmt:
|
||||||
var atyp *itype
|
var atyp *itype
|
||||||
if n.nleft+n.nright < len(n.child) {
|
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 {
|
if atyp, err = nodeType(interp, sc, n.child[n.nleft]); err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ func isRecursiveStruct(t *itype, rtype reflect.Type) bool {
|
|||||||
if t.cat == structT && rtype.Kind() == reflect.Interface {
|
if t.cat == structT && rtype.Kind() == reflect.Interface {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if t.cat == ptrT {
|
if t.cat == ptrT && t.rtype != nil {
|
||||||
return isRecursiveStruct(t.val, t.rtype.Elem())
|
return isRecursiveStruct(t.val, t.rtype.Elem())
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -885,7 +885,9 @@ func (t *itype) refType(defined map[string]bool) reflect.Type {
|
|||||||
panic(err)
|
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
|
t.val.rtype = interf
|
||||||
}
|
}
|
||||||
switch t.cat {
|
switch t.cat {
|
||||||
|
|||||||
Reference in New Issue
Block a user