Skip to content

Commit

Permalink
feat: handle nil case
Browse files Browse the repository at this point in the history
  • Loading branch information
omarsy committed Nov 2, 2024
1 parent 7d935f6 commit 7f89510
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 10 deletions.
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -2184,7 +2184,7 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node {

// TRANS_LEAVE -----------------------
case *ValueDecl:
assertValidAssignRhs(store, last, n.Values)
assertValidAssignRhs(store, last, n)

// evaluate value if const expr.
if n.Const {
Expand Down
38 changes: 29 additions & 9 deletions gnovm/pkg/gnolang/type_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ func (x *RangeStmt) AssertCompatible(store Store, last BlockNode) {

func (x *AssignStmt) AssertCompatible(store Store, last BlockNode) {
if x.Op == ASSIGN || x.Op == DEFINE {
assertValidAssignRhs(store, last, x.Rhs)
assertValidAssignRhs(store, last, x)
if len(x.Lhs) > len(x.Rhs) {
if len(x.Rhs) != 1 {
panic(fmt.Sprintf("assignment mismatch: %d variables but %d values", len(x.Lhs), len(x.Rhs)))
Expand Down Expand Up @@ -915,17 +915,37 @@ func assertValidAssignLhs(store Store, last BlockNode, lx Expr) {
}
}

func assertValidAssignRhs(store Store, last BlockNode, exps Exprs) {
func assertValidAssignRhs(store Store, last BlockNode, n Node) {
var exps []Expr
switch x := n.(type) {
case *ValueDecl:
exps = x.Values

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

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/type_check.go#L921-L922

Added lines #L921 - L922 were not covered by tests
case *AssignStmt:
exps = x.Rhs
default:
panic(fmt.Sprintf("unexpected node type %T", n))
}

for _, exp := range exps {
switch n := exp.(type) {
case *CallExpr, *TypeAssertExpr, *IndexExpr:
default:
tt := evalStaticTypeOf(store, last, n)
if _, ok := tt.(*TypeType); ok {
tt = evalStaticType(store, last, n)
panic(fmt.Sprintf("%s (type) is not an expression", tt.String()))
tt := evalStaticTypeOfRaw(store, last, exp)
if tt == nil {
switch x := n.(type) {
case *ValueDecl:
if x.Type != nil {
continue
}
panic("use of untyped nil in variable declaration")
case *AssignStmt:
if x.Op != DEFINE {
continue
}
panic("use of untyped nil in assignment")
}
}
if _, ok := tt.(*TypeType); ok {
tt = evalStaticType(store, last, exp)
panic(fmt.Sprintf("%s (type) is not an expression", tt.String()))
}
}
}

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

func main() {
a := nil
println(a)
}

// Error:
// main/files/assign31.gno:4:2: use of untyped nil in assignment
8 changes: 8 additions & 0 deletions gnovm/tests/files/var32.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package main

func main() {
var t = nil
}

// Error:
// main/files/var32.gno:4:6: use of untyped nil in variable declaration
9 changes: 9 additions & 0 deletions gnovm/tests/files/var33.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

func main() {
var t *int = nil
println("pass")
}

// Output:
// pass

0 comments on commit 7f89510

Please sign in to comment.