fix: handle type assertion from literal interface type
This commit is contained in:
committed by
Traefiker Bot
parent
c5ec5e492f
commit
08a37fc4bf
12
_test/composite3.go
Normal file
12
_test/composite3.go
Normal 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
11
_test/composite4.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
_, ok := err.(interface{ IsSet() bool })
|
||||
println(ok)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// false
|
||||
@@ -517,7 +517,11 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
n.child[l].gen = getIndexMap2
|
||||
n.gen = nop
|
||||
case typeAssertExpr:
|
||||
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:
|
||||
types = append(types, n.child[l].child[1].typ, sc.getType("bool"))
|
||||
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.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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user