diff --git a/pkg/compiler/analysis.go b/pkg/compiler/analysis.go index b3ca6954a..79827d303 100644 --- a/pkg/compiler/analysis.go +++ b/pkg/compiler/analysis.go @@ -282,7 +282,14 @@ func (c *codegen) visitPkg(pkg *packages.Package, seen map[string]bool) { return } for _, imp := range pkg.Types.Imports() { - c.visitPkg(pkg.Imports[imp.Path()], seen) + var subpkg = pkg.Imports[imp.Path()] + if subpkg == nil { + if c.prog.Err == nil { + c.prog.Err = fmt.Errorf("failed to load %q package from %q, import cycle?", imp.Path(), pkg.PkgPath) + } + return + } + c.visitPkg(subpkg, seen) } seen[pkg.PkgPath] = true c.packages = append(c.packages, pkg.PkgPath) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 957a508e7..e03866aad 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -2209,6 +2209,9 @@ func (c *codegen) newLambda(u uint16, lit *ast.FuncLit) { func (c *codegen) compile(info *buildInfo, pkg *packages.Package) error { c.mainPkg = pkg c.analyzePkgOrder() + if c.prog.Err != nil { + return c.prog.Err + } c.fillDocumentInfo() funUsage := c.analyzeFuncAndGlobalVarUsage() if c.prog.Err != nil { diff --git a/pkg/compiler/import_test.go b/pkg/compiler/import_test.go index 9080209f4..967d387b1 100644 --- a/pkg/compiler/import_test.go +++ b/pkg/compiler/import_test.go @@ -2,7 +2,11 @@ package compiler_test import ( "math/big" + "strings" "testing" + + "github.com/nspcc-dev/neo-go/pkg/compiler" + "github.com/stretchr/testify/require" ) func TestImportFunction(t *testing.T) { @@ -61,3 +65,27 @@ func TestImportNameSameAsOwn(t *testing.T) { }` eval(t, src, big.NewInt(3)) } + +func TestImportCycleDirect(t *testing.T) { + src := ` + package some + import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg2" + func Main() int { + return pkg2.A + } + ` + _, _, err := compiler.CompileWithOptions("some.go", strings.NewReader(src), nil) + require.Error(t, err) +} + +func TestImportCycleIndirect(t *testing.T) { + src := ` + package some + import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg1" + func Main() int { + return pkg1.A + } + ` + _, _, err := compiler.CompileWithOptions("some.go", strings.NewReader(src), nil) + require.Error(t, err) +} diff --git a/pkg/compiler/testdata/importcycle/pkg1/pkg1.go b/pkg/compiler/testdata/importcycle/pkg1/pkg1.go new file mode 100644 index 000000000..63bdc4fb7 --- /dev/null +++ b/pkg/compiler/testdata/importcycle/pkg1/pkg1.go @@ -0,0 +1,9 @@ +package pkg1 + +import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg2" + +var A int + +func init() { + pkg2.A = 1 +} diff --git a/pkg/compiler/testdata/importcycle/pkg2/pkg2.go b/pkg/compiler/testdata/importcycle/pkg2/pkg2.go new file mode 100644 index 000000000..f80a896d3 --- /dev/null +++ b/pkg/compiler/testdata/importcycle/pkg2/pkg2.go @@ -0,0 +1,11 @@ +package pkg2 + +import ( + "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg3" +) + +var A int + +func init() { + pkg3.A = 2 +} diff --git a/pkg/compiler/testdata/importcycle/pkg3/pkg3.go b/pkg/compiler/testdata/importcycle/pkg3/pkg3.go new file mode 100644 index 000000000..35abab456 --- /dev/null +++ b/pkg/compiler/testdata/importcycle/pkg3/pkg3.go @@ -0,0 +1,11 @@ +package pkg3 + +import ( + "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg2" +) + +var A int + +func init() { + pkg2.A = 1 +}