@@ -221,9 +221,7 @@ func (s *snapshot) load(ctx context.Context, allowNetwork bool, scopes ...loadSc
221
221
if allFilesExcluded (pkg .GoFiles , filterFunc ) {
222
222
continue
223
223
}
224
- if err := buildMetadata (ctx , pkg , cfg , query , newMetadata , nil ); err != nil {
225
- return err
226
- }
224
+ buildMetadata (newMetadata , pkg , cfg .Dir , query )
227
225
}
228
226
229
227
s .mu .Lock ()
@@ -448,7 +446,7 @@ func (s *snapshot) applyCriticalErrorToFiles(ctx context.Context, msg string, fi
448
446
// buildMetadata populates the updates map with metadata updates to
449
447
// apply, based on the given pkg. It recurs through pkg.Imports to ensure that
450
448
// 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 ) {
452
450
// Allow for multiple ad-hoc packages in the workspace (see #47584).
453
451
pkgPath := PackagePath (pkg .PkgPath )
454
452
id := PackageID (pkg .ID )
@@ -465,26 +463,14 @@ func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Con
465
463
pkgPath = PackagePath (pkg .PkgPath + suffix )
466
464
}
467
465
466
+ // Duplicate?
468
467
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
488
474
}
489
475
490
476
// 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
494
480
Name : PackageName (pkg .Name ),
495
481
ForTest : PackagePath (packagesinternal .GetForTest (pkg )),
496
482
TypesSizes : pkg .TypesSizes ,
497
- LoadDir : cfg . Dir ,
483
+ LoadDir : loadDir ,
498
484
Module : pkg .Module ,
499
485
Errors : pkg .Errors ,
500
486
DepsErrors : packagesinternal .GetDepsErrors (pkg ),
@@ -598,17 +584,13 @@ func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Con
598
584
599
585
depsByImpPath [importPath ] = PackageID (imported .ID )
600
586
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 )
604
588
}
605
589
m .DepsByImpPath = depsByImpPath
606
590
m .DepsByPkgPath = depsByPkgPath
607
591
608
592
// m.Diagnostics is set later in the loading pass, using
609
593
// computeLoadDiagnostics.
610
-
611
- return nil
612
594
}
613
595
614
596
// computeLoadDiagnostics computes and sets m.Diagnostics for the given metadata m.
0 commit comments