From 6a820f53acb59d118bf5ab4b946ddf3d21d6a63f Mon Sep 17 00:00:00 2001 From: HaraldNordgren Date: Sat, 6 Jan 2018 20:35:42 +0100 Subject: [PATCH] cmd/go: special error message for direct self import This attempts to sort out confusion about cyclical imports. In addition to the error message "import cycle not allowed", for direct self imports we will now instead give a specialized error message, namely: self import not allowed Fixes #23295 Change-Id: I14e2418aa4eceb8caf2e6520c686fac7e85cb0dd --- src/cmd/go/go_test.go | 16 ++++++++++++++++ src/cmd/go/internal/load/pkg.go | 15 ++++++++++++++- src/cmd/go/testdata/importcycle/cycle.go | 3 +++ src/cmd/go/testdata/importcycle/selfimport.go | 3 +++ .../go/testdata/importcycle/src/cycle1/cycle1.go | 6 ++++++ .../go/testdata/importcycle/src/cycle2/cycle2.go | 3 +++ .../importcycle/src/noncyclic/noncyclic.go | 1 + .../importcycle/src/selfimport/selfimport.go | 6 ++++++ 8 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/cmd/go/testdata/importcycle/cycle.go create mode 100644 src/cmd/go/testdata/importcycle/selfimport.go create mode 100644 src/cmd/go/testdata/importcycle/src/cycle1/cycle1.go create mode 100644 src/cmd/go/testdata/importcycle/src/cycle2/cycle2.go create mode 100644 src/cmd/go/testdata/importcycle/src/noncyclic/noncyclic.go create mode 100644 src/cmd/go/testdata/importcycle/src/selfimport/selfimport.go diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 371296c72e6260..450ce9ce275f76 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -1351,6 +1351,22 @@ func TestImportCommentConflict(t *testing.T) { tg.grepStderr("found import comments", "go build did not mention comment conflict") } +func TestImportCycle(t *testing.T) { + tg := testgo(t) + defer tg.cleanup() + tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcycle")) + tg.runFail("build", "./testdata/importcycle/cycle.go") + tg.grepStderr("import cycle not allowed", "go build did not mention cyclical import") +} + +func TestImportCycleSelfImport(t *testing.T) { + tg := testgo(t) + defer tg.cleanup() + tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcycle")) + tg.runFail("build", "./testdata/importcycle/selfimport.go") + tg.grepStderr("self import not allowed", "go build did not mention self import") +} + // cmd/go: custom import path checking should not apply to Go packages without import comment. func TestIssue10952(t *testing.T) { testenv.MustHaveExternalNetwork(t) diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 2b3d7fd0e1a3c5..77de42353913c7 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -598,6 +598,19 @@ func hasGoFiles(dir string) bool { return false } +// getImportError returns the error message for cyclical imports. It gives a +// special message for a packages that directly imports itself. For all other +// cyclical imports it gives a general message about import cycles. +func getImportError(p *Package) string { + for _, i := range p.Imports { + if i == p.ImportPath { + return "self import not allowed" + } + } + + return "import cycle not allowed" +} + // reusePackage reuses package p to satisfy the import at the top // of the import stack stk. If this use causes an import loop, // reusePackage updates p's error information to record the loop. @@ -609,7 +622,7 @@ func reusePackage(p *Package, stk *ImportStack) *Package { if p.Error == nil { p.Error = &PackageError{ ImportStack: stk.Copy(), - Err: "import cycle not allowed", + Err: getImportError(p), IsImportCycle: true, } } diff --git a/src/cmd/go/testdata/importcycle/cycle.go b/src/cmd/go/testdata/importcycle/cycle.go new file mode 100644 index 00000000000000..e6b34dfb3f54d2 --- /dev/null +++ b/src/cmd/go/testdata/importcycle/cycle.go @@ -0,0 +1,3 @@ +package p + +import "cycle1" diff --git a/src/cmd/go/testdata/importcycle/selfimport.go b/src/cmd/go/testdata/importcycle/selfimport.go new file mode 100644 index 00000000000000..ea5a03fdef1231 --- /dev/null +++ b/src/cmd/go/testdata/importcycle/selfimport.go @@ -0,0 +1,3 @@ +package p + +import "selfimport" diff --git a/src/cmd/go/testdata/importcycle/src/cycle1/cycle1.go b/src/cmd/go/testdata/importcycle/src/cycle1/cycle1.go new file mode 100644 index 00000000000000..f416aa0df7f827 --- /dev/null +++ b/src/cmd/go/testdata/importcycle/src/cycle1/cycle1.go @@ -0,0 +1,6 @@ +package cycle1 + +import ( + "_noncyclic" + "cycle2" +) diff --git a/src/cmd/go/testdata/importcycle/src/cycle2/cycle2.go b/src/cmd/go/testdata/importcycle/src/cycle2/cycle2.go new file mode 100644 index 00000000000000..2ad7be5165dd86 --- /dev/null +++ b/src/cmd/go/testdata/importcycle/src/cycle2/cycle2.go @@ -0,0 +1,3 @@ +package cycle2 + +import "cycle1" diff --git a/src/cmd/go/testdata/importcycle/src/noncyclic/noncyclic.go b/src/cmd/go/testdata/importcycle/src/noncyclic/noncyclic.go new file mode 100644 index 00000000000000..82db7c1ab5e4be --- /dev/null +++ b/src/cmd/go/testdata/importcycle/src/noncyclic/noncyclic.go @@ -0,0 +1 @@ +package _noncyclic diff --git a/src/cmd/go/testdata/importcycle/src/selfimport/selfimport.go b/src/cmd/go/testdata/importcycle/src/selfimport/selfimport.go new file mode 100644 index 00000000000000..b643934f63761f --- /dev/null +++ b/src/cmd/go/testdata/importcycle/src/selfimport/selfimport.go @@ -0,0 +1,6 @@ +package selfimport + +import ( + "_noncyclic" + "selfimport" +)