fix: parsing of recursive interface types
This commit is contained in:
37
_test/interface36.go
Normal file
37
_test/interface36.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
var (
|
||||||
|
t *S
|
||||||
|
_ I = t
|
||||||
|
_ J = t
|
||||||
|
)
|
||||||
|
|
||||||
|
type S struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *S) F() int { return len(s.Name) }
|
||||||
|
func (s *S) G() int { return s.F() }
|
||||||
|
func (s *S) Ri() I { return s }
|
||||||
|
func (s *S) Rj() J { return s }
|
||||||
|
|
||||||
|
type J interface {
|
||||||
|
I
|
||||||
|
G() int
|
||||||
|
Rj() J
|
||||||
|
}
|
||||||
|
|
||||||
|
type I interface {
|
||||||
|
F() int
|
||||||
|
Ri() I
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var j J
|
||||||
|
fmt.Println(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
@@ -423,6 +423,7 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
|||||||
|
|
||||||
case interfaceType:
|
case interfaceType:
|
||||||
t.cat = interfaceT
|
t.cat = interfaceT
|
||||||
|
var incomplete bool
|
||||||
if sname := typeName(n); sname != "" {
|
if sname := typeName(n); sname != "" {
|
||||||
if sym, _, found := sc.lookup(sname); found && sym.kind == typeSym {
|
if sym, _, found := sc.lookup(sname); found && sym.kind == typeSym {
|
||||||
sym.typ = t
|
sym.typ = t
|
||||||
@@ -435,16 +436,17 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t.field = append(t.field, structField{name: fieldName(field.child[0]), embed: true, typ: typ})
|
t.field = append(t.field, structField{name: fieldName(field.child[0]), embed: true, typ: typ})
|
||||||
t.incomplete = t.incomplete || typ.incomplete
|
incomplete = incomplete || typ.incomplete
|
||||||
} else {
|
} else {
|
||||||
typ, err := nodeType(interp, sc, field.child[1])
|
typ, err := nodeType(interp, sc, field.child[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t.field = append(t.field, structField{name: field.child[0].ident, typ: typ})
|
t.field = append(t.field, structField{name: field.child[0].ident, typ: typ})
|
||||||
t.incomplete = t.incomplete || typ.incomplete
|
incomplete = incomplete || typ.incomplete
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
t.incomplete = incomplete
|
||||||
|
|
||||||
case landExpr, lorExpr:
|
case landExpr, lorExpr:
|
||||||
t.cat = boolT
|
t.cat = boolT
|
||||||
|
|||||||
Reference in New Issue
Block a user