Skip to content

Commit 17e5ef3

Browse files
committed
gopls/internal/lsp/cache: remove cycle check from buildMetadata
The metadataGraph now takes care of cycle checking, and is able to do so more thoroughly. Change-Id: I00ff4a88ffb4ec12300c566651f82a878f25eb31 Reviewed-on: https://go-review.googlesource.com/c/tools/+/491295 Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Alan Donovan <[email protected]>
1 parent affb5fc commit 17e5ef3

File tree

1 file changed

+11
-29
lines changed

1 file changed

+11
-29
lines changed

gopls/internal/lsp/cache/load.go

+11-29
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,7 @@ func (s *snapshot) load(ctx context.Context, allowNetwork bool, scopes ...loadSc
221221
if allFilesExcluded(pkg.GoFiles, filterFunc) {
222222
continue
223223
}
224-
if err := buildMetadata(ctx, pkg, cfg, query, newMetadata, nil); err != nil {
225-
return err
226-
}
224+
buildMetadata(newMetadata, pkg, cfg.Dir, query)
227225
}
228226

229227
s.mu.Lock()
@@ -448,7 +446,7 @@ func (s *snapshot) applyCriticalErrorToFiles(ctx context.Context, msg string, fi
448446
// buildMetadata populates the updates map with metadata updates to
449447
// apply, based on the given pkg. It recurs through pkg.Imports to ensure that
450448
// metadata exists for all dependencies.
451-
func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Config, query []string, updates map[PackageID]*source.Metadata, path []PackageID) error {
449+
func buildMetadata(updates map[PackageID]*source.Metadata, pkg *packages.Package, loadDir string, query []string) {
452450
// Allow for multiple ad-hoc packages in the workspace (see #47584).
453451
pkgPath := PackagePath(pkg.PkgPath)
454452
id := PackageID(pkg.ID)
@@ -465,26 +463,14 @@ func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Con
465463
pkgPath = PackagePath(pkg.PkgPath + suffix)
466464
}
467465

466+
// Duplicate?
468467
if _, ok := updates[id]; ok {
469-
// If we've already seen this dependency, there may be an import cycle, or
470-
// we may have reached the same package transitively via distinct paths.
471-
// Check the path to confirm.
472-
473-
// TODO(rfindley): this doesn't look sufficient. Any single piece of new
474-
// metadata could theoretically introduce import cycles in the metadata
475-
// graph. What's the point of this limited check here (and is it even
476-
// possible to get an import cycle in data from go/packages)? Consider
477-
// simply returning, so that this function need not return an error.
478-
//
479-
// We should consider doing a more complete guard against import cycles
480-
// elsewhere.
481-
// [Update: we do! breakImportCycles in metadataGraph.Clone. Delete this.]
482-
for _, prev := range path {
483-
if prev == id {
484-
return fmt.Errorf("import cycle detected: %q", id)
485-
}
486-
}
487-
return nil
468+
// A package was encountered twice due to shared
469+
// subgraphs (common) or cycles (rare). Although "go
470+
// list" usually breaks cycles, we don't rely on it.
471+
// breakImportCycles in metadataGraph.Clone takes care
472+
// of it later.
473+
return
488474
}
489475

490476
// Recreate the metadata rather than reusing it to avoid locking.
@@ -494,7 +480,7 @@ func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Con
494480
Name: PackageName(pkg.Name),
495481
ForTest: PackagePath(packagesinternal.GetForTest(pkg)),
496482
TypesSizes: pkg.TypesSizes,
497-
LoadDir: cfg.Dir,
483+
LoadDir: loadDir,
498484
Module: pkg.Module,
499485
Errors: pkg.Errors,
500486
DepsErrors: packagesinternal.GetDepsErrors(pkg),
@@ -598,17 +584,13 @@ func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Con
598584

599585
depsByImpPath[importPath] = PackageID(imported.ID)
600586
depsByPkgPath[PackagePath(imported.PkgPath)] = PackageID(imported.ID)
601-
if err := buildMetadata(ctx, imported, cfg, query, updates, append(path, id)); err != nil {
602-
event.Error(ctx, "error in dependency", err)
603-
}
587+
buildMetadata(updates, imported, loadDir, query)
604588
}
605589
m.DepsByImpPath = depsByImpPath
606590
m.DepsByPkgPath = depsByPkgPath
607591

608592
// m.Diagnostics is set later in the loading pass, using
609593
// computeLoadDiagnostics.
610-
611-
return nil
612594
}
613595

614596
// computeLoadDiagnostics computes and sets m.Diagnostics for the given metadata m.

0 commit comments

Comments
 (0)