Skip to content

Commit

Permalink
interp: fix testing for nil interface values
Browse files Browse the repository at this point in the history
Fixes #924.
  • Loading branch information
mvertes committed Oct 30, 2020
1 parent 7f8ffa6 commit a38d192
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
28 changes: 28 additions & 0 deletions _test/nil3.go
@@ -0,0 +1,28 @@
package main

type I interface {
Hello()
}

type T struct {
h I
}

func (t *T) Hello() { println("Hello") }

func main() {
t := &T{}
println(t.h != nil)
println(t.h == nil)
t.h = t
println(t.h != nil)
println(t.h == nil)
t.h.Hello()
}

// Output:
// false
// true
// true
// false
// Hello
26 changes: 18 additions & 8 deletions interp/run.go
Expand Up @@ -3091,9 +3091,9 @@ func isNil(n *node) {
fnext := getExec(n.fnext)
if c0.typ.cat == interfaceT {
n.exec = func(f *frame) bltn {
vi := value(f).Interface().(valueInterface)
if (vi == valueInterface{} ||
vi.node.kind == basicLit && vi.node.typ.cat == nilT) {
v := value(f)
vi, ok := v.Interface().(valueInterface)
if ok && (vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) || v.IsNil() {
dest(f).SetBool(true)
return tnext
}
Expand All @@ -3113,7 +3113,12 @@ func isNil(n *node) {
} else {
if c0.typ.cat == interfaceT {
n.exec = func(f *frame) bltn {
dest(f).SetBool(value(f).Interface().(valueInterface) == valueInterface{})
v := value(f)
if vi, ok := v.Interface().(valueInterface); ok {
dest(f).SetBool(vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT)
} else {
dest(f).SetBool(v.IsNil())
}
return tnext
}
} else {
Expand All @@ -3140,9 +3145,9 @@ func isNotNil(n *node) {
fnext := getExec(n.fnext)
if c0.typ.cat == interfaceT {
n.exec = func(f *frame) bltn {
vi := value(f).Interface().(valueInterface)
if (vi == valueInterface{} ||
vi.node.kind == basicLit && vi.node.typ.cat == nilT) {
v := value(f)
vi, ok := v.Interface().(valueInterface)
if ok && (vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) || v.IsNil() {
dest(f).SetBool(false)
return fnext
}
Expand All @@ -3162,7 +3167,12 @@ func isNotNil(n *node) {
} else {
if c0.typ.cat == interfaceT {
n.exec = func(f *frame) bltn {
dest(f).SetBool(!(value(f).Interface().(valueInterface) == valueInterface{}))
v := value(f)
if vi, ok := v.Interface().(valueInterface); ok {
dest(f).SetBool(!(vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT))
} else {
dest(f).SetBool(!v.IsNil())
}
return tnext
}
} else {
Expand Down

0 comments on commit a38d192

Please sign in to comment.