@@ -258,13 +258,21 @@ type driverResponse struct {
258
258
// proceeding with further analysis. The PrintErrors function is
259
259
// provided for convenient display of all errors.
260
260
func Load (cfg * Config , patterns ... string ) ([]* Package , error ) {
261
- l := newLoader (cfg )
262
- response , err := defaultDriver (& l .Config , patterns ... )
261
+ ld := newLoader (cfg )
262
+ response , err := defaultDriver (& ld .Config , patterns ... )
263
263
if err != nil {
264
264
return nil , err
265
265
}
266
- l .sizes = types .SizesFor (response .Compiler , response .Arch )
267
- return l .refine (response )
266
+
267
+ // If type size information is needed but unavailable.
268
+ // reject the whole Load since the error is the same for every package.
269
+ ld .sizes = types .SizesFor (response .Compiler , response .Arch )
270
+ if ld .sizes == nil && ld .Config .Mode & (NeedTypes | NeedTypesSizes | NeedTypesInfo ) != 0 {
271
+ return nil , fmt .Errorf ("can't determine type sizes for compiler %q on GOARCH %q" ,
272
+ response .Compiler , response .Arch )
273
+ }
274
+
275
+ return ld .refine (response )
268
276
}
269
277
270
278
// defaultDriver is a driver that implements go/packages' fallback behavior.
@@ -553,7 +561,7 @@ type loaderPackage struct {
553
561
type loader struct {
554
562
pkgs map [string ]* loaderPackage
555
563
Config
556
- sizes types.Sizes
564
+ sizes types.Sizes // non-nil if needed by mode
557
565
parseCache map [string ]* parseValue
558
566
parseCacheMu sync.Mutex
559
567
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
@@ -678,7 +686,7 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
678
686
}
679
687
}
680
688
681
- // Materialize the import graph.
689
+ // Materialize the import graph (if NeedImports) .
682
690
683
691
const (
684
692
white = 0 // new
@@ -696,9 +704,8 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
696
704
// visit returns whether the package needs src or has a transitive
697
705
// dependency on a package that does. These are the only packages
698
706
// for which we load source code.
699
- var stack []* loaderPackage
707
+ var stack , srcPkgs []* loaderPackage
700
708
var visit func (lpkg * loaderPackage ) bool
701
- var srcPkgs []* loaderPackage
702
709
visit = func (lpkg * loaderPackage ) bool {
703
710
switch lpkg .color {
704
711
case black :
@@ -709,35 +716,34 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
709
716
lpkg .color = grey
710
717
stack = append (stack , lpkg ) // push
711
718
stubs := lpkg .Imports // the structure form has only stubs with the ID in the Imports
712
- // If NeedImports isn't set, the imports fields will all be zeroed out.
713
- if ld .Mode & NeedImports != 0 {
714
- lpkg .Imports = make (map [string ]* Package , len (stubs ))
715
- for importPath , ipkg := range stubs {
716
- var importErr error
717
- imp := ld .pkgs [ipkg .ID ]
718
- if imp == nil {
719
- // (includes package "C" when DisableCgo)
720
- importErr = fmt .Errorf ("missing package: %q" , ipkg .ID )
721
- } else if imp .color == grey {
722
- importErr = fmt .Errorf ("import cycle: %s" , stack )
723
- }
724
- if importErr != nil {
725
- if lpkg .importErrors == nil {
726
- lpkg .importErrors = make (map [string ]error )
727
- }
728
- lpkg .importErrors [importPath ] = importErr
729
- continue
719
+ lpkg .Imports = make (map [string ]* Package , len (stubs ))
720
+ for importPath , ipkg := range stubs {
721
+ var importErr error
722
+ imp := ld .pkgs [ipkg .ID ]
723
+ if imp == nil {
724
+ // (includes package "C" when DisableCgo)
725
+ importErr = fmt .Errorf ("missing package: %q" , ipkg .ID )
726
+ } else if imp .color == grey {
727
+ importErr = fmt .Errorf ("import cycle: %s" , stack )
728
+ }
729
+ if importErr != nil {
730
+ if lpkg .importErrors == nil {
731
+ lpkg .importErrors = make (map [string ]error )
730
732
}
733
+ lpkg .importErrors [importPath ] = importErr
734
+ continue
735
+ }
731
736
732
- if visit (imp ) {
733
- lpkg .needsrc = true
734
- }
735
- lpkg .Imports [importPath ] = imp .Package
737
+ if visit (imp ) {
738
+ lpkg .needsrc = true
736
739
}
740
+ lpkg .Imports [importPath ] = imp .Package
737
741
}
738
742
if lpkg .needsrc {
739
743
srcPkgs = append (srcPkgs , lpkg )
740
744
}
745
+ // NeedTypeSizes causes TypeSizes to be set even
746
+ // on packages for which types aren't needed.
741
747
if ld .Mode & NeedTypesSizes != 0 {
742
748
lpkg .TypesSizes = ld .sizes
743
749
}
@@ -757,17 +763,18 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
757
763
for _ , lpkg := range initial {
758
764
visit (lpkg )
759
765
}
760
- }
761
- if ld .Mode & NeedImports != 0 && ld .Mode & NeedTypes != 0 {
762
- for _ , lpkg := range srcPkgs {
766
+
767
+ if ld .Mode & NeedTypes != 0 {
763
768
// Complete type information is required for the
764
769
// immediate dependencies of each source package.
765
- for _ , ipkg := range lpkg .Imports {
766
- imp := ld .pkgs [ipkg .ID ]
767
- imp .needtypes = true
770
+ for _ , lpkg := range srcPkgs {
771
+ for _ , ipkg := range lpkg .Imports {
772
+ ld .pkgs [ipkg .ID ].needtypes = true
773
+ }
768
774
}
769
775
}
770
776
}
777
+
771
778
// Load type data and syntax if needed, starting at
772
779
// the initial packages (roots of the import DAG).
773
780
if ld .Mode & NeedTypes != 0 || ld .Mode & NeedSyntax != 0 {
@@ -1042,7 +1049,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
1042
1049
IgnoreFuncBodies : ld .Mode & NeedDeps == 0 && ! lpkg .initial ,
1043
1050
1044
1051
Error : appendError ,
1045
- Sizes : ld .sizes ,
1052
+ Sizes : ld .sizes , // may be nil
1046
1053
}
1047
1054
if lpkg .Module != nil && lpkg .Module .GoVersion != "" {
1048
1055
typesinternal .SetGoVersion (tc , "go" + lpkg .Module .GoVersion )
0 commit comments