Skip to content

Commit eaeb445

Browse files
authored
interp: create interpreter interface value with new
In that case, the interface must be wrapped in an valueInterface at creation. With that fix, it is now possible to import github.com/google/go-querystring/query. Not tested beyond that. Fixes #1123.
1 parent 6933ba2 commit eaeb445

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

interp/cfg.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
13241324
// retry with the filename, in case ident is a package name.
13251325
sym, level, found = sc.lookup(filepath.Join(n.ident, baseName))
13261326
if !found {
1327-
err = n.cfgErrorf("undefined: %s %d", n.ident, n.index)
1327+
err = n.cfgErrorf("undefined: %s", n.ident)
13281328
break
13291329
}
13301330
}

interp/interp_eval_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,29 @@ func TestEvalBinCall(t *testing.T) {
709709
})
710710
}
711711

712+
func TestEvalReflect(t *testing.T) {
713+
i := interp.New(interp.Options{})
714+
if err := i.Use(stdlib.Symbols); err != nil {
715+
t.Fatal(err)
716+
}
717+
if _, err := i.Eval(`
718+
import (
719+
"net/url"
720+
"reflect"
721+
)
722+
723+
type Encoder interface {
724+
EncodeValues(key string, v *url.Values) error
725+
}
726+
`); err != nil {
727+
t.Fatal(err)
728+
}
729+
730+
runTests(t, i, []testCase{
731+
{src: "reflect.TypeOf(new(Encoder)).Elem()", res: "interp.valueInterface"},
732+
})
733+
}
734+
712735
func TestEvalMissingSymbol(t *testing.T) {
713736
defer func() {
714737
r := recover()

interp/run.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3303,11 +3303,20 @@ func _len(n *node) {
33033303

33043304
func _new(n *node) {
33053305
next := getExec(n.tnext)
3306-
typ := n.child[1].typ.TypeOf()
3306+
t1 := n.child[1].typ
3307+
typ := t1.TypeOf()
33073308
dest := genValueOutput(n, reflect.PtrTo(typ))
33083309

3310+
if isInterfaceSrc(t1) && (!isEmptyInterface(t1) || len(t1.method) > 0) {
3311+
typ = zeroInterfaceValue().Type()
3312+
}
3313+
33093314
n.exec = func(f *frame) bltn {
3310-
dest(f).Set(reflect.New(typ))
3315+
v := reflect.New(typ)
3316+
if vi, ok := v.Interface().(*valueInterface); ok {
3317+
vi.node = n
3318+
}
3319+
dest(f).Set(v)
33113320
return next
33123321
}
33133322
}

0 commit comments

Comments
 (0)