Skip to content

Commit 2ea21f5

Browse files
committed
fix(#1966): go2Gno loses type info
1 parent 5429655 commit 2ea21f5

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

gnovm/pkg/gnolang/preprocess.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,17 +882,26 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node {
882882
// Left not const, Right not const ------------------
883883
if n.Op == EQL || n.Op == NEQ {
884884
// If == or !=, no conversions.
885-
} else if lnt, ok := lt.(*NativeType); ok {
885+
} else if ok, lnt := func() (bool, *NativeType) {
886+
lnt, okl := lt.(*NativeType)
887+
_, okr := rt.(*NativeType)
888+
return okl && okr, lnt
889+
}(); ok {
886890
if debug {
887891
if !isShift {
888892
assertSameTypes(lt, rt)
889893
}
890894
}
891-
// If left and right are native type,
895+
// If left and right are native type, and same type
892896
// convert left and right to gno, then
893897
// convert result back to native.
894898
//
895899
// get concrete native base type.
900+
if lt.TypeID() != rt.TypeID() {
901+
panic(fmt.Sprintf(
902+
"incompatible types in binary expression: %v %v %v",
903+
n.Left, n.Op, n.Right))
904+
}
896905
pt := go2GnoBaseType(lnt.Type).(PrimitiveType)
897906
// convert n.Left to (gno) pt type,
898907
ln := Expr(Call(pt.String(), n.Left))

gnovm/pkg/gnolang/preprocess_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package gnolang
2+
3+
import (
4+
"bytes"
5+
"reflect"
6+
"testing"
7+
"time"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestPrepocessBinaryExpressionPrimaryAndNative(t *testing.T) {
13+
t.Parallel()
14+
15+
out := new(bytes.Buffer)
16+
pkg := NewPackageNode("time", "time", nil)
17+
pkg.DefineGoNativeValue("Millisecond", time.Millisecond)
18+
pkg.DefineGoNativeValue("Second", time.Second)
19+
pkg.DefineGoNativeType(reflect.TypeOf(time.Duration(0)))
20+
pv := pkg.NewPackage()
21+
store := gonativeTestStore(pkg, pv)
22+
23+
m := NewMachineWithOptions(MachineOptions{
24+
PkgPath: "main",
25+
Output: out,
26+
Store: store,
27+
})
28+
29+
c := `package main
30+
import "time"
31+
func main() {
32+
var a int64 = 2
33+
println(a * time.Second)
34+
35+
}`
36+
n := MustParseFile("main.go", c)
37+
assert.Panics(t, func() { m.RunFiles(n) }, "should panic: invalid operation: int64 * time.Duration")
38+
}
39+
40+
func TestPrepocessBinaryExpressionNativeAndNative(t *testing.T) {
41+
t.Parallel()
42+
43+
out := new(bytes.Buffer)
44+
pkg := NewPackageNode("time", "time", nil)
45+
pkg.DefineGoNativeValue("March", time.March)
46+
pkg.DefineGoNativeValue("Wednesday", time.Wednesday)
47+
pkg.DefineGoNativeType(reflect.TypeOf(time.Month(0)))
48+
pkg.DefineGoNativeType(reflect.TypeOf(time.Weekday(0)))
49+
pv := pkg.NewPackage()
50+
store := gonativeTestStore(pkg, pv)
51+
52+
m := NewMachineWithOptions(MachineOptions{
53+
PkgPath: "main",
54+
Output: out,
55+
Store: store,
56+
})
57+
58+
c := `package main
59+
import "time"
60+
func main() {
61+
println(time.March * time.Wednesday)
62+
63+
}`
64+
n := MustParseFile("main.go", c)
65+
assert.Panics(t, func() { m.RunFiles(n) }, "should panic: invalid operation: time.Month * time.Weekday")
66+
}

0 commit comments

Comments
 (0)