fix: type assertion expression was not forwarding type
The detection of special cases of interpreter functions and interfaces is more precise. It allows at least to complete parsing of code where type is derived from a type assertion expression. Fixes #770.
This commit is contained in:
25
_test/issue-770.go
Normal file
25
_test/issue-770.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
|
||||
type I interface {
|
||||
Foo() int
|
||||
}
|
||||
|
||||
type T struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (t T) Foo() int { return 0 }
|
||||
|
||||
func f(v reflect.Value) int {
|
||||
i := v.Interface().(I)
|
||||
return i.Foo()
|
||||
}
|
||||
|
||||
func main() {
|
||||
println("hello")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
@@ -1725,17 +1725,18 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
|
||||
case typeAssertExpr:
|
||||
if len(n.child) > 1 {
|
||||
wireChild(n)
|
||||
if n.child[1].typ == nil {
|
||||
if n.child[1].typ, err = nodeType(interp, sc, n.child[1]); err != nil {
|
||||
c1 := n.child[1]
|
||||
if c1.typ == nil {
|
||||
if c1.typ, err = nodeType(interp, sc, c1); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if n.anc.action != aAssignX {
|
||||
if n.child[0].typ.cat == valueT && !isStruct(n.child[1].typ) {
|
||||
if n.child[0].typ.cat == valueT && isFunc(c1.typ) {
|
||||
// Avoid special wrapping of interfaces and func types.
|
||||
n.typ = &itype{cat: valueT, rtype: n.child[1].typ.TypeOf()}
|
||||
n.typ = &itype{cat: valueT, rtype: c1.typ.TypeOf()}
|
||||
} else {
|
||||
n.typ = n.child[1].typ
|
||||
n.typ = c1.typ
|
||||
}
|
||||
n.findex = sc.add(n.typ)
|
||||
}
|
||||
|
||||
@@ -1536,11 +1536,13 @@ func chanElement(t *itype) *itype {
|
||||
|
||||
func isBool(t *itype) bool { return t.TypeOf().Kind() == reflect.Bool }
|
||||
func isChan(t *itype) bool { return t.TypeOf().Kind() == reflect.Chan }
|
||||
func isFunc(t *itype) bool { return t.TypeOf().Kind() == reflect.Func }
|
||||
func isMap(t *itype) bool { return t.TypeOf().Kind() == reflect.Map }
|
||||
func isSendChan(t *itype) bool {
|
||||
rt := t.TypeOf()
|
||||
return rt.Kind() == reflect.Chan && rt.ChanDir() == reflect.SendDir
|
||||
}
|
||||
func isMap(t *itype) bool { return t.TypeOf().Kind() == reflect.Map }
|
||||
|
||||
func isArray(t *itype) bool {
|
||||
k := t.TypeOf().Kind()
|
||||
return k == reflect.Array || k == reflect.Slice
|
||||
|
||||
Reference in New Issue
Block a user