fix: handle type assertion from literal interface type

This commit is contained in:
Marc Vertes
2019-11-19 14:50:06 +01:00
committed by Traefiker Bot
parent c5ec5e492f
commit 08a37fc4bf
4 changed files with 69 additions and 4 deletions

12
_test/composite3.go Normal file
View File

@@ -0,0 +1,12 @@
package main
func main() {
var err error
var ok bool
_, ok = err.(interface{ IsSet() bool })
println(ok)
}
// Output:
// false

11
_test/composite4.go Normal file
View File

@@ -0,0 +1,11 @@
package main
func main() {
var err error
_, ok := err.(interface{ IsSet() bool })
println(ok)
}
// Output:
// false

View File

@@ -517,7 +517,11 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
n.child[l].gen = getIndexMap2
n.gen = nop
case typeAssertExpr:
n.child[l].gen = typeAssert2
if n.child[0].ident == "_" {
n.child[l].gen = typeAssertStatus
} else {
n.child[l].gen = typeAssert2
}
n.gen = nop
case unaryExpr:
if n.child[l].action == aRecv {
@@ -1314,7 +1318,9 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
if len(n.child) > 1 {
wireChild(n)
if n.child[1].typ == nil {
n.child[1].typ = sc.getType(n.child[1].ident)
if n.child[1].typ, err = nodeType(interp, sc, n.child[1]); err != nil {
return
}
}
if n.anc.action != aAssignX {
n.typ = n.child[1].typ
@@ -1386,8 +1392,12 @@ func compDefineX(sc *scope, n *node) error {
n.gen = nop
case typeAssertExpr:
if n.child[0].ident == "_" {
n.child[l].gen = typeAssertStatus
} else {
n.child[l].gen = typeAssert2
}
types = append(types, n.child[l].child[1].typ, sc.getType("bool"))
n.child[l].gen = typeAssert2
n.gen = nop
case unaryExpr:
@@ -1595,7 +1605,8 @@ func isKey(n *node) bool {
return n.anc.kind == fileStmt ||
(n.anc.kind == selectorExpr && n.anc.child[0] != n) ||
(n.anc.kind == funcDecl && isMethod(n.anc)) ||
(n.anc.kind == keyValueExpr && isStruct(n.anc.typ) && n.anc.child[0] == n)
(n.anc.kind == keyValueExpr && isStruct(n.anc.typ) && n.anc.child[0] == n) ||
(n.anc.kind == fieldExpr && len(n.anc.child) > 1 && n.anc.child[0] == n)
}
// isNewDefine returns true if node refers to a new definition

View File

@@ -119,6 +119,37 @@ func runCfg(n *node, f *frame) {
}
}
func typeAssertStatus(n *node) {
value := genValue(n.child[0]) // input value
value1 := genValue(n.anc.child[1]) // returned status
next := getExec(n.tnext)
switch {
case n.child[0].typ.cat == valueT:
n.exec = func(f *frame) bltn {
if !value(f).IsValid() || value(f).IsNil() {
value1(f).SetBool(false)
}
value1(f).SetBool(true)
return next
}
case n.child[1].typ.cat == interfaceT:
n.exec = func(f *frame) bltn {
_, ok := value(f).Interface().(valueInterface)
//value0(f).Set(reflect.ValueOf(valueInterface{v.node, v.value}))
value1(f).SetBool(ok)
return next
}
default:
n.exec = func(f *frame) bltn {
_, ok := value(f).Interface().(valueInterface)
//value0(f).Set(v.value)
value1(f).SetBool(ok)
return next
}
}
}
func typeAssert(n *node) {
value := genValue(n.child[0])
i := n.findex