diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 9168fc6f7c1..100edcb2601 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -457,6 +457,9 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { case *AssignStmt: checkValDefineMismatch(n) + for _, rx := range n.Rhs { + checkExprIsAssignable(rx) + } if n.Op == DEFINE { for _, lx := range n.Lhs { ln := lx.(*NameExpr).Name @@ -489,6 +492,9 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { d := n.(Decl) if cd, ok := d.(*ValueDecl); ok { checkValDefineMismatch(cd) + for _, rx := range cd.Values { + checkExprIsAssignable(rx) + } } // recursively predefine dependencies. d2, ppd := predefineNow(store, last, d) diff --git a/gnovm/pkg/gnolang/type_check.go b/gnovm/pkg/gnolang/type_check.go index 31025fef152..cb3059c2098 100644 --- a/gnovm/pkg/gnolang/type_check.go +++ b/gnovm/pkg/gnolang/type_check.go @@ -279,6 +279,29 @@ func checkValDefineMismatch(n Node) { panic(fmt.Sprintf("assignment mismatch: %d variable(s) but %d value(s)", numNames, numValues)) } +func checkExprIsAssignable(exp Expr) { + switch exp.(type) { + case *NameExpr, + *BasicLitExpr, + *BinaryExpr, + *CallExpr, + *IndexExpr, + *SelectorExpr, + *SliceExpr, + *StarExpr, + *RefExpr, + *TypeAssertExpr, + *UnaryExpr, + *CompositeLitExpr, + *KeyValueExpr, + *FuncLitExpr, + *ConstExpr: + return + } + + panic(fmt.Sprintf("%s (type) is not an expression", exp.String())) +} + // Assert that xt can be assigned as dt (dest type). // If autoNative is true, a broad range of xt can match against // a target native dt type, if and only if dt is a native type. diff --git a/gnovm/tests/files/assign29.gno b/gnovm/tests/files/assign29.gno new file mode 100644 index 00000000000..747b7051ea6 --- /dev/null +++ b/gnovm/tests/files/assign29.gno @@ -0,0 +1,8 @@ +package main + +func main() { + t := struct{} +} + +// Error: +// main/files/assign29.gno:4:2: struct { } (type) is not an expression diff --git a/gnovm/tests/files/var31.gno b/gnovm/tests/files/var31.gno new file mode 100644 index 00000000000..036bc19f828 --- /dev/null +++ b/gnovm/tests/files/var31.gno @@ -0,0 +1,8 @@ +package main + +func main() { + var t = struct{} +} + +// Error: +// main/files/var31.gno:4:6: struct { } (type) is not an expression