Skip to content

Commit

Permalink
fix(gnovm): enhance constant evaluation for array and map types
Browse files Browse the repository at this point in the history
  • Loading branch information
omarsy committed Dec 26, 2024
1 parent 9001059 commit c45f63e
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 13 deletions.
33 changes: 23 additions & 10 deletions gnovm/pkg/gnolang/type_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,22 @@ Main:
}
panic(fmt.Sprintf("%s (variable of type %s) is not constant", currExpr.Name, t))
case *TypeAssertExpr:
ty := evalStaticTypeOf(store, last, currExpr)
_, okCallExpr := parentExpr.(*CallExpr)
_, okArray := ty.(*ArrayType)
if okCallExpr && okArray {
break Main

Check warning on line 264 in gnovm/pkg/gnolang/type_check.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/type_check.go#L264

Added line #L264 was not covered by tests
}
panic(fmt.Sprintf("%s (comma, ok expression of type %s) is not constant", currExpr.String(), currExpr.Type))
case *IndexExpr:
ty := evalStaticTypeOf(store, last, currExpr)
_, okCallExpr := parentExpr.(*CallExpr)
_, okArray := ty.(*ArrayType)
if okCallExpr && okArray {
// TODO: should add a test after the fix of https://github.com/gnolang/gno/issues/3409
break Main
}

panic(fmt.Sprintf("%s (variable of type %s) is not constant", currExpr.String(), currExpr.X))
case *CallExpr:
ift := evalStaticTypeOf(store, last, currExpr.Func)
Expand Down Expand Up @@ -334,14 +348,15 @@ Main:

tt := pv.GetBlock(store).Source.GetStaticTypeOf(store, currExpr.Sel)
panic(fmt.Sprintf("%s (variable of type %s) is not constant", currExpr.String(), tt))

Check warning on line 350 in gnovm/pkg/gnolang/type_check.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/type_check.go#L349-L350

Added lines #L349 - L350 were not covered by tests
case *PointerType, *DeclaredType, *StructType, *InterfaceType:
ty := evalStaticTypeOf(store, last, currExpr.X)
panic(fmt.Sprintf("%s (variable of type %s) is not constant", currExpr.String(), ty))
case *TypeType:
ty := evalStaticType(store, last, currExpr.X)
panic(fmt.Sprintf("%s (variable of type %s) is not constant", currExpr.String(), ty))
case *NativeType:
ty := evalStaticTypeOf(store, last, currExpr.X)
case *PointerType, *DeclaredType, *StructType, *InterfaceType, *TypeType, *NativeType:
ty := evalStaticTypeOf(store, last, currExpr)
_, okCallExpr := parentExpr.(*CallExpr)
_, okArray := ty.(*ArrayType)

// special case for len, cap
if okCallExpr && okArray {
break Main
}
panic(fmt.Sprintf("%s (variable of type %s) is not constant", currExpr.String(), ty))
default:
panic(fmt.Sprintf(
Expand All @@ -356,8 +371,6 @@ Main:
}
case *ConstExpr:
case *BasicLitExpr:

Check warning on line 373 in gnovm/pkg/gnolang/type_check.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/type_check.go#L373

Added line #L373 was not covered by tests
case *CompositeLitExpr:
assertValidConstValue(store, last, currExpr.Type, parentExpr)
default:
ift := evalStaticTypeOf(store, last, currExpr)
if _, ok := ift.(*TypeType); ok {
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/const32.gno
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ func main() {
}

// Error:
// main/files/const32.gno:6:8: [](const-type string) (variable of type []string) is not constant
// main/files/const32.gno:6:8: [](const-type string){} (variable of type []string) is not constant
2 changes: 1 addition & 1 deletion gnovm/tests/files/const36.gno
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ func main() {
}

// Error:
// main/files/const36.gno:9:8: s<VPBlock(1,0)>.x (variable of type main.s) is not constant
// main/files/const36.gno:9:8: s<VPBlock(1,0)>.x (variable of type int) is not constant
2 changes: 1 addition & 1 deletion gnovm/tests/files/const38.gno
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ func main() {
}

// Error:
// main/files/const38.gno:7:8: v<VPBlock(1,0)>.Denom (variable of type std.Coin) is not constant
// main/files/const38.gno:7:8: v<VPBlock(1,0)>.Denom (variable of type string) is not constant
14 changes: 14 additions & 0 deletions gnovm/tests/files/const45_a.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

type MyStruct struct {
arr [2]int
}

const a = len(MyStruct{arr: [2]int{1, 2}}.arr)

func main() {
println("ok")
}

// Output:
// ok
14 changes: 14 additions & 0 deletions gnovm/tests/files/const45_b.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

type MyStruct struct {
arr []int
}

const a = len(MyStruct{arr: []int{1, 2}}.arr)

func main() {
println("ok")
}

// Error:
// main/files/const45_b.gno:7:7: MyStruct<VPBlock(2,0)>{arr<VPField(0,0,arr)>: [](const-type int){(const (1 int)), (const (2 int))}}.arr (variable of type []int) is not constant
10 changes: 10 additions & 0 deletions gnovm/tests/files/const46.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

const a = len(map[string][2]int{"arr": {1, 2}}["arr"])

func main() {
println("ok")
}

// Output:
// ok
10 changes: 10 additions & 0 deletions gnovm/tests/files/const47.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

const a = len(map[string][2]interface{}{"arr": {1, 2}}["arr"])

func main() {
println("ok")
}

// Output:
// ok
9 changes: 9 additions & 0 deletions gnovm/tests/files/const48.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

func main() {
const a = len(map[string][]int{"arr": {1, 2}})
println("ok", a)
}

// Error:
// main/files/const48.gno:4:8: map[(const-type string)] [](const-type int){(const ("arr" string)): (const-type []int){(const (1 int)), (const (2 int))}} (variable of type map[string][]int) is not constant

0 comments on commit c45f63e

Please sign in to comment.