go/loader: fix race
Fixes golang/go#36415.
Change-Id: I1bdec3da8e2a4f185e039a0046731a3300ee1153
Reviewed-on: https://go-review.googlesource.com/c/tools/+/293836
gopls-CI: kokoro <noreply+kokoro@google.com>
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/go/loader/loader.go b/go/loader/loader.go
index bc12ca3..508a1fd 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -869,21 +869,6 @@
// caused these imports.
//
func (imp *importer) importAll(fromPath, fromDir string, imports map[string]bool, mode build.ImportMode) (infos []*PackageInfo, errors []importError) {
- // TODO(adonovan): opt: do the loop in parallel once
- // findPackage is non-blocking.
- var pending []*importInfo
- for importPath := range imports {
- bp, err := imp.findPackage(importPath, fromDir, mode)
- if err != nil {
- errors = append(errors, importError{
- path: importPath,
- err: err,
- })
- continue
- }
- pending = append(pending, imp.startLoad(bp))
- }
-
if fromPath != "" {
// We're loading a set of imports.
//
@@ -895,29 +880,36 @@
deps = make(map[string]bool)
imp.graph[fromPath] = deps
}
- for _, ii := range pending {
- deps[ii.path] = true
+ for importPath := range imports {
+ deps[importPath] = true
}
imp.graphMu.Unlock()
}
- for _, ii := range pending {
+ var pending []*importInfo
+ for importPath := range imports {
if fromPath != "" {
- if cycle := imp.findPath(ii.path, fromPath); cycle != nil {
- // Cycle-forming import: we must not await its
- // completion since it would deadlock.
- //
- // We don't record the error in ii since
- // the error is really associated with the
- // cycle-forming edge, not the package itself.
- // (Also it would complicate the
- // invariants of importPath completion.)
+ if cycle := imp.findPath(importPath, fromPath); cycle != nil {
+ // Cycle-forming import: we must not check it
+ // since it would deadlock.
if trace {
fmt.Fprintf(os.Stderr, "import cycle: %q\n", cycle)
}
continue
}
}
+ bp, err := imp.findPackage(importPath, fromDir, mode)
+ if err != nil {
+ errors = append(errors, importError{
+ path: importPath,
+ err: err,
+ })
+ continue
+ }
+ pending = append(pending, imp.startLoad(bp))
+ }
+
+ for _, ii := range pending {
ii.awaitCompletion()
infos = append(infos, ii.info)
}