fix: improving handling of functions returning interfaces
This commit is contained in:
11
_test/fun15.go
Normal file
11
_test/fun15.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
func f1(a int) interface{} { return a + 1 }
|
||||
|
||||
func main() {
|
||||
c := f1(3)
|
||||
println(c.(int))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
13
_test/fun16.go
Normal file
13
_test/fun16.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
func f1(a int) int { return a + 1 }
|
||||
|
||||
func f2(a int) interface{} { return f1(a) }
|
||||
|
||||
func main() {
|
||||
c := f2(3)
|
||||
println(c.(int))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
13
_test/fun17.go
Normal file
13
_test/fun17.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
func f1(a int) interface{} { return a + 1 }
|
||||
|
||||
func f2(a int) interface{} { return f1(a) }
|
||||
|
||||
func main() {
|
||||
c := f2(3)
|
||||
println(c.(int))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
12
_test/fun18.go
Normal file
12
_test/fun18.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
var m = map[string]int{"foo": 1, "bar": 2}
|
||||
|
||||
func f(s string) interface{} { return m[s] }
|
||||
|
||||
func main() {
|
||||
println(f("foo").(int))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
11
_test/map26.go
Normal file
11
_test/map26.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
var m = map[string]int{"foo": 1, "bar": 2}
|
||||
|
||||
func main() {
|
||||
var a interface{} = m["foo"]
|
||||
println(a.(int))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
@@ -684,7 +684,19 @@ func call(n *node) {
|
||||
// Function call from a return statement: forward return values (always at frame start).
|
||||
for i := range rtypes {
|
||||
j := i
|
||||
rvalues[i] = func(f *frame) reflect.Value { return f.data[j] }
|
||||
ret := n.child[0].typ.ret[i]
|
||||
callret := n.anc.val.(*node).typ.ret[i]
|
||||
if callret.cat == interfaceT && ret.cat != interfaceT {
|
||||
// Wrap the returned value in a valueInterface in caller frame.
|
||||
rvalues[i] = func(f *frame) reflect.Value {
|
||||
v := reflect.New(ret.rtype).Elem()
|
||||
f.data[j].Set(reflect.ValueOf(valueInterface{n, v}))
|
||||
return v
|
||||
}
|
||||
} else {
|
||||
// Set the return value location in return value of caller frame.
|
||||
rvalues[i] = func(f *frame) reflect.Value { return f.data[j] }
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Multiple return values frame index are indexed from the node frame index.
|
||||
|
||||
@@ -253,10 +253,13 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
}
|
||||
// If the node is to be assigned or returned, the node type is the destination type.
|
||||
dt := t
|
||||
if a := n.anc; a.kind == defineStmt && len(a.child) > a.nleft+a.nright {
|
||||
switch a := n.anc; {
|
||||
case a.kind == defineStmt && len(a.child) > a.nleft+a.nright:
|
||||
if dt, err = nodeType(interp, sc, a.child[a.nleft]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case a.kind == returnStmt:
|
||||
dt = sc.def.typ.ret[childPos(n)]
|
||||
}
|
||||
if isInterface(dt) {
|
||||
dt.val = t
|
||||
|
||||
Reference in New Issue
Block a user