Skip to content

fix(#1966): go2Gno loses type info #2016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 23, 2024
13 changes: 11 additions & 2 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,17 +882,26 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node {
// Left not const, Right not const ------------------
if n.Op == EQL || n.Op == NEQ {
// If == or !=, no conversions.
} else if lnt, ok := lt.(*NativeType); ok {
} else if ok, lnt := func() (bool, *NativeType) {
lnt, okl := lt.(*NativeType)
_, okr := rt.(*NativeType)
return okl && okr, lnt
}(); ok {
if debug {
if !isShift {
assertSameTypes(lt, rt)
}
}
// If left and right are native type,
// If left and right are native type, and same type
// convert left and right to gno, then
// convert result back to native.
//
// get concrete native base type.
if lt.TypeID() != rt.TypeID() {
panic(fmt.Sprintf(
"incompatible types in binary expression: %v %v %v",
n.Left, n.Op, n.Right))
}
pt := go2GnoBaseType(lnt.Type).(PrimitiveType)
// convert n.Left to (gno) pt type,
ln := Expr(Call(pt.String(), n.Left))
Expand Down
66 changes: 66 additions & 0 deletions gnovm/pkg/gnolang/preprocess_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package gnolang

import (
"bytes"
"reflect"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestPrepocessBinaryExpressionPrimaryAndNative(t *testing.T) {
t.Parallel()

out := new(bytes.Buffer)
pkg := NewPackageNode("time", "time", nil)
pkg.DefineGoNativeValue("Millisecond", time.Millisecond)
pkg.DefineGoNativeValue("Second", time.Second)
pkg.DefineGoNativeType(reflect.TypeOf(time.Duration(0)))
pv := pkg.NewPackage()
store := gonativeTestStore(pkg, pv)

m := NewMachineWithOptions(MachineOptions{
PkgPath: "main",
Output: out,
Store: store,
})

c := `package main
import "time"
func main() {
var a int64 = 2
println(a * time.Second)

}`
n := MustParseFile("main.go", c)
assert.Panics(t, func() { m.RunFiles(n) }, "should panic: invalid operation: int64 * time.Duration")
}

func TestPrepocessBinaryExpressionNativeAndNative(t *testing.T) {
t.Parallel()

out := new(bytes.Buffer)
pkg := NewPackageNode("time", "time", nil)
pkg.DefineGoNativeValue("March", time.March)
pkg.DefineGoNativeValue("Wednesday", time.Wednesday)
pkg.DefineGoNativeType(reflect.TypeOf(time.Month(0)))
pkg.DefineGoNativeType(reflect.TypeOf(time.Weekday(0)))
pv := pkg.NewPackage()
store := gonativeTestStore(pkg, pv)

m := NewMachineWithOptions(MachineOptions{
PkgPath: "main",
Output: out,
Store: store,
})

c := `package main
import "time"
func main() {
println(time.March * time.Wednesday)

}`
n := MustParseFile("main.go", c)
assert.Panics(t, func() { m.RunFiles(n) }, "should panic: invalid operation: time.Month * time.Weekday")
}
Loading