Skip to content

Commit

Permalink
fix(gnolang): prescriptively reject *ast.(IndexListExpr, GoStmt) as u…
Browse files Browse the repository at this point in the history
…nrecognized for Gno

The *ast.IndexListExpr is used for generics but in assignment operations
it is illegal to use. This change returns a proper error and matches
Go's output.
Also *ast.GoStmt is for spawning Go routines but those are forbidden
in Gno, hence reject them prescriptively instead of just spewing
out the raw ast type.

Fixes #3731
Updates #3751
  • Loading branch information
odeke-em committed Feb 22, 2025
1 parent 85b3c0b commit 4e46182
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
9 changes: 8 additions & 1 deletion gnovm/cmd/gno/tool_lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,12 @@ var reParseRecover = regexp.MustCompile(`^([^:]+)((?::(?:\d+)){1,2}):? *(.*)$`)

func catchRuntimeError(pkgPath string, stderr goio.WriteCloser, action func()) (hasError bool) {
defer func() {
// Errors catched here mostly come from: gnovm/pkg/gnolang/preprocess.go
// Errors caught here mostly come from: gnovm/pkg/gnolang/preprocess.go
r := recover()
if r == nil {
return
}

hasError = true
switch verr := r.(type) {
case *gno.PreprocessError:
Expand Down Expand Up @@ -303,6 +304,12 @@ func issueFromError(pkgPath string, err error) lintIssue {
issue.Confidence = 1
issue.Code = lintGnoError

if ewp, ok := err.(*gno.LocationPlusError); ok {
issue.Location = ewp.Location()
issue.Msg = ewp.Message()
return issue
}

parsedError := strings.TrimSpace(err.Error())
parsedError = strings.TrimPrefix(parsedError, pkgPath+"/")

Expand Down
8 changes: 8 additions & 0 deletions gnovm/pkg/gnolang/go2gno.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ func Go2Gno(fs *token.FileSet, gon ast.Node) (n Node) {
if len(gon.Recv.List) > 1 {
panicWithPos("method has multiple receivers")
}

if len(gon.Recv.List) == 0 {
panicWithPos("method has no receiver")
}
Expand Down Expand Up @@ -478,6 +479,13 @@ func Go2Gno(fs *token.FileSet, gon ast.Node) (n Node) {
}
case *ast.EmptyStmt:
return &EmptyStmt{}
case *ast.IndexListExpr:
if len(gon.Indices) > 1 {
panicWithPos("invalid operation: more than one index"})

Check failure on line 484 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / test (1.23.x)

syntax error: unexpected } in argument list; possibly missing comma or )

Check failure on line 484 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / Run gno fmt on stdlibs / fmt

syntax error: unexpected } in argument list; possibly missing comma or )

Check failure on line 484 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / gno2go (1.23.x)

syntax error: unexpected } in argument list; possibly missing comma or )

Check failure on line 484 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / Run gno fmt on examples / fmt

syntax error: unexpected } in argument list; possibly missing comma or )
}
panicWithPos("invalid operation: indexList is not permitted in Gno"})

Check failure on line 486 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / test (1.23.x)

syntax error: unexpected } in argument list; possibly missing comma or )

Check failure on line 486 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / Run gno fmt on stdlibs / fmt

syntax error: unexpected } in argument list; possibly missing comma or )

Check failure on line 486 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / gno2go (1.23.x)

syntax error: unexpected } in argument list; possibly missing comma or )

Check failure on line 486 in gnovm/pkg/gnolang/go2gno.go

View workflow job for this annotation

GitHub Actions / Run gno fmt on examples / fmt

syntax error: unexpected } in argument list; possibly missing comma or )
case *ast.GoStmt:
panicWithPos("goroutines are not permitted"})
default:
panicWithPos("unknown Go type %v: %s\n",
reflect.TypeOf(gon),
Expand Down
16 changes: 16 additions & 0 deletions gnovm/tests/files/goroutine_not_supported.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// https://github.com/gnolang/gno/issues/3751

package math

import "testing"

func Add(a, b int) int {
return a + b
}

func TestAdd(t *testing.T) {
go Add(1, 1)
}

// Error:
// files/goroutine_not_supported.gno:12:5: goroutines are not permitted
16 changes: 16 additions & 0 deletions gnovm/tests/files/parse_indexListExpr.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// https://github.com/gnolang/gno/issues/3731

package main

type node struct {
r []int
}

func (n *node) foo(targ, wndex int) {
_ = n.r[targ, wndex]
}

func main() {}

// ERROR:
// files/parse_indexListExpr.gno:10:6: invalid operation: more than one index

0 comments on commit 4e46182

Please sign in to comment.