Skip to content

Commit 4a80936

Browse files
authored
interp: fix handling interface in operators
In case of interface values, make sure that the concrete type is preserved during type inference. Fixes #1466.
1 parent 7865c90 commit 4a80936

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

_test/issue-1466.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
func SomeFunc(defaultValue interface{}) interface{} {
8+
switch v := defaultValue.(type) {
9+
case string:
10+
return v + " abc"
11+
case int:
12+
return v - 234
13+
}
14+
panic("whoops")
15+
}
16+
17+
func main() {
18+
fmt.Println(SomeFunc(1234))
19+
fmt.Println(SomeFunc("test"))
20+
}
21+
22+
// Output:
23+
// 1000
24+
// test abc

interp/cfg.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
679679
n.gen = nop
680680
src.findex = dest.findex
681681
src.level = level
682-
case len(n.child) < 4 && isArithmeticAction(src):
682+
case len(n.child) < 4 && isArithmeticAction(src) && !isInterface(dest.typ):
683683
// Optimize single assignments from some arithmetic operations.
684684
src.typ = dest.typ
685685
src.findex = dest.findex
@@ -828,9 +828,7 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
828828
case n.anc.kind == returnStmt:
829829
// To avoid a copy in frame, if the result is to be returned, store it directly
830830
// at the frame location reserved for output arguments.
831-
pos := childPos(n)
832-
n.typ = sc.def.typ.ret[pos]
833-
n.findex = pos
831+
n.findex = childPos(n)
834832
default:
835833
// Allocate a new location in frame, and store the result here.
836834
n.findex = sc.add(n.typ)

interp/type.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,10 @@ func nodeType2(interp *Interpreter, sc *scope, n *node, seen []*node) (t *itype,
598598
}
599599

600600
if isInterfaceSrc(dt) {
601-
dt.val = t
601+
// Set a new interface type preserving the concrete type (.val field).
602+
t2 := *dt
603+
t2.val = t
604+
dt = &t2
602605
}
603606
t = dt
604607

0 commit comments

Comments
 (0)