interp: fix handling interface in operators
In case of interface values, make sure that the concrete type is preserved during type inference. Fixes #1466.
This commit is contained in:
24
_test/issue-1466.go
Normal file
24
_test/issue-1466.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func SomeFunc(defaultValue interface{}) interface{} {
|
||||
switch v := defaultValue.(type) {
|
||||
case string:
|
||||
return v + " abc"
|
||||
case int:
|
||||
return v - 234
|
||||
}
|
||||
panic("whoops")
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(SomeFunc(1234))
|
||||
fmt.Println(SomeFunc("test"))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1000
|
||||
// test abc
|
||||
@@ -679,7 +679,7 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
|
||||
n.gen = nop
|
||||
src.findex = dest.findex
|
||||
src.level = level
|
||||
case len(n.child) < 4 && isArithmeticAction(src):
|
||||
case len(n.child) < 4 && isArithmeticAction(src) && !isInterface(dest.typ):
|
||||
// Optimize single assignments from some arithmetic operations.
|
||||
src.typ = dest.typ
|
||||
src.findex = dest.findex
|
||||
@@ -828,9 +828,7 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
|
||||
case n.anc.kind == returnStmt:
|
||||
// To avoid a copy in frame, if the result is to be returned, store it directly
|
||||
// at the frame location reserved for output arguments.
|
||||
pos := childPos(n)
|
||||
n.typ = sc.def.typ.ret[pos]
|
||||
n.findex = pos
|
||||
n.findex = childPos(n)
|
||||
default:
|
||||
// Allocate a new location in frame, and store the result here.
|
||||
n.findex = sc.add(n.typ)
|
||||
|
||||
@@ -598,7 +598,10 @@ func nodeType2(interp *Interpreter, sc *scope, n *node, seen []*node) (t *itype,
|
||||
}
|
||||
|
||||
if isInterfaceSrc(dt) {
|
||||
dt.val = t
|
||||
// Set a new interface type preserving the concrete type (.val field).
|
||||
t2 := *dt
|
||||
t2.val = t
|
||||
dt = &t2
|
||||
}
|
||||
t = dt
|
||||
|
||||
|
||||
Reference in New Issue
Block a user