]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/load/pkg.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[gostls13.git] / src / cmd / go / internal / load / pkg.go
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package load loads packages.
6 package load
7
8 import (
9         "bytes"
10         "context"
11         "encoding/json"
12         "errors"
13         "fmt"
14         "go/build"
15         "go/scanner"
16         "go/token"
17         "internal/goroot"
18         "io/fs"
19         "os"
20         "path"
21         pathpkg "path"
22         "path/filepath"
23         "runtime"
24         "runtime/debug"
25         "sort"
26         "strconv"
27         "strings"
28         "time"
29         "unicode"
30         "unicode/utf8"
31
32         "cmd/go/internal/base"
33         "cmd/go/internal/cfg"
34         "cmd/go/internal/fsys"
35         "cmd/go/internal/imports"
36         "cmd/go/internal/modfetch"
37         "cmd/go/internal/modinfo"
38         "cmd/go/internal/modload"
39         "cmd/go/internal/par"
40         "cmd/go/internal/search"
41         "cmd/go/internal/str"
42         "cmd/go/internal/trace"
43         "cmd/go/internal/vcs"
44         "cmd/internal/sys"
45
46         "golang.org/x/mod/modfile"
47         "golang.org/x/mod/module"
48 )
49
50 // A Package describes a single package found in a directory.
51 type Package struct {
52         PackagePublic                 // visible in 'go list'
53         Internal      PackageInternal // for use inside go command only
54 }
55
56 type PackagePublic struct {
57         // Note: These fields are part of the go command's public API.
58         // See list.go. It is okay to add fields, but not to change or
59         // remove existing ones. Keep in sync with list.go
60         Dir           string                `json:",omitempty"` // directory containing package sources
61         ImportPath    string                `json:",omitempty"` // import path of package in dir
62         ImportComment string                `json:",omitempty"` // path in import comment on package statement
63         Name          string                `json:",omitempty"` // package name
64         Doc           string                `json:",omitempty"` // package documentation string
65         Target        string                `json:",omitempty"` // installed target for this package (may be executable)
66         Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
67         Root          string                `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package
68         ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
69         ForTest       string                `json:",omitempty"` // package is only for use in named test
70         Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
71         BuildID       string                `json:",omitempty"` // build ID of the compiled package (set by go list -export)
72         Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
73         Match         []string              `json:",omitempty"` // command-line patterns matching this package
74         Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
75         Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?
76         DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed
77         BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled
78         Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?
79
80         // Stale and StaleReason remain here *only* for the list command.
81         // They are only initialized in preparation for list execution.
82         // The regular build determines staleness on the fly during action execution.
83         Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
84         StaleReason string `json:",omitempty"` // why is Stale true?
85
86         // Source files
87         // If you add to this list you MUST add to p.AllFiles (below) too.
88         // Otherwise file name security lists will not apply to any new additions.
89         GoFiles           []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
90         CgoFiles          []string `json:",omitempty"` // .go source files that import "C"
91         CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles
92         IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints
93         InvalidGoFiles    []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)
94         IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints
95         CFiles            []string `json:",omitempty"` // .c source files
96         CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files
97         MFiles            []string `json:",omitempty"` // .m source files
98         HFiles            []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
99         FFiles            []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files
100         SFiles            []string `json:",omitempty"` // .s source files
101         SwigFiles         []string `json:",omitempty"` // .swig files
102         SwigCXXFiles      []string `json:",omitempty"` // .swigcxx files
103         SysoFiles         []string `json:",omitempty"` // .syso system object files added to package
104
105         // Embedded files
106         EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
107         EmbedFiles    []string `json:",omitempty"` // files matched by EmbedPatterns
108
109         // Cgo directives
110         CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
111         CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
112         CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
113         CgoFFLAGS    []string `json:",omitempty"` // cgo: flags for Fortran compiler
114         CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
115         CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
116
117         // Dependency information
118         Imports   []string          `json:",omitempty"` // import paths used by this package
119         ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
120         Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies
121
122         // Error information
123         // Incomplete is above, packed into the other bools
124         Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
125         DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
126
127         // Test information
128         // If you add to this list you MUST add to p.AllFiles (below) too.
129         // Otherwise file name security lists will not apply to any new additions.
130         TestGoFiles        []string `json:",omitempty"` // _test.go files in package
131         TestImports        []string `json:",omitempty"` // imports from TestGoFiles
132         TestEmbedPatterns  []string `json:",omitempty"` // //go:embed patterns
133         TestEmbedFiles     []string `json:",omitempty"` // files matched by TestEmbedPatterns
134         XTestGoFiles       []string `json:",omitempty"` // _test.go files outside package
135         XTestImports       []string `json:",omitempty"` // imports from XTestGoFiles
136         XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
137         XTestEmbedFiles    []string `json:",omitempty"` // files matched by XTestEmbedPatterns
138 }
139
140 // AllFiles returns the names of all the files considered for the package.
141 // This is used for sanity and security checks, so we include all files,
142 // even IgnoredGoFiles, because some subcommands consider them.
143 // The go/build package filtered others out (like foo_wrongGOARCH.s)
144 // and that's OK.
145 func (p *Package) AllFiles() []string {
146         files := str.StringList(
147                 p.GoFiles,
148                 p.CgoFiles,
149                 // no p.CompiledGoFiles, because they are from GoFiles or generated by us
150                 p.IgnoredGoFiles,
151                 // no p.InvalidGoFiles, because they are from GoFiles
152                 p.IgnoredOtherFiles,
153                 p.CFiles,
154                 p.CXXFiles,
155                 p.MFiles,
156                 p.HFiles,
157                 p.FFiles,
158                 p.SFiles,
159                 p.SwigFiles,
160                 p.SwigCXXFiles,
161                 p.SysoFiles,
162                 p.TestGoFiles,
163                 p.XTestGoFiles,
164         )
165
166         // EmbedFiles may overlap with the other files.
167         // Dedup, but delay building the map as long as possible.
168         // Only files in the current directory (no slash in name)
169         // need to be checked against the files variable above.
170         var have map[string]bool
171         for _, file := range p.EmbedFiles {
172                 if !strings.Contains(file, "/") {
173                         if have == nil {
174                                 have = make(map[string]bool)
175                                 for _, file := range files {
176                                         have[file] = true
177                                 }
178                         }
179                         if have[file] {
180                                 continue
181                         }
182                 }
183                 files = append(files, file)
184         }
185         return files
186 }
187
188 // Desc returns the package "description", for use in b.showOutput.
189 func (p *Package) Desc() string {
190         if p.ForTest != "" {
191                 return p.ImportPath + " [" + p.ForTest + ".test]"
192         }
193         return p.ImportPath
194 }
195
196 type PackageInternal struct {
197         // Unexported fields are not part of the public API.
198         Build             *build.Package
199         Imports           []*Package           // this package's direct imports
200         CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
201         RawImports        []string             // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
202         ForceLibrary      bool                 // this package is a library (even if named "main")
203         CmdlineFiles      bool                 // package built from files listed on command line
204         CmdlinePkg        bool                 // package listed on command line
205         CmdlinePkgLiteral bool                 // package listed as literal on command line (not via wildcard)
206         Local             bool                 // imported via local path (./ or ../)
207         LocalPrefix       string               // interpret ./ and ../ imports relative to this prefix
208         ExeName           string               // desired name for temporary executable
209         FuzzInstrument    bool                 // package should be instrumented for fuzzing
210         CoverMode         string               // preprocess Go source files with the coverage tool in this mode
211         CoverVars         map[string]*CoverVar // variables created by coverage analysis
212         OmitDebug         bool                 // tell linker not to write debug information
213         GobinSubdir       bool                 // install target would be subdir of GOBIN
214         BuildInfo         string               // add this info to package main
215         TestmainGo        *[]byte              // content for _testmain.go
216         Embed             map[string][]string  // //go:embed comment mapping
217         OrigImportPath    string               // original import path before adding '_test' suffix
218
219         Asmflags   []string // -asmflags for this package
220         Gcflags    []string // -gcflags for this package
221         Ldflags    []string // -ldflags for this package
222         Gccgoflags []string // -gccgoflags for this package
223 }
224
225 // A NoGoError indicates that no Go files for the package were applicable to the
226 // build for that package.
227 //
228 // That may be because there were no files whatsoever, or because all files were
229 // excluded, or because all non-excluded files were test sources.
230 type NoGoError struct {
231         Package *Package
232 }
233
234 func (e *NoGoError) Error() string {
235         if len(e.Package.IgnoredGoFiles) > 0 {
236                 // Go files exist, but they were ignored due to build constraints.
237                 return "build constraints exclude all Go files in " + e.Package.Dir
238         }
239         if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {
240                 // Test Go files exist, but we're not interested in them.
241                 // The double-negative is unfortunate but we want e.Package.Dir
242                 // to appear at the end of error message.
243                 return "no non-test Go files in " + e.Package.Dir
244         }
245         return "no Go files in " + e.Package.Dir
246 }
247
248 // setLoadPackageDataError presents an error found when loading package data
249 // as a *PackageError. It has special cases for some common errors to improve
250 // messages shown to users and reduce redundancy.
251 //
252 // setLoadPackageDataError returns true if it's safe to load information about
253 // imported packages, for example, if there was a parse error loading imports
254 // in one file, but other files are okay.
255 func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {
256         matchErr, isMatchErr := err.(*search.MatchError)
257         if isMatchErr && matchErr.Match.Pattern() == path {
258                 if matchErr.Match.IsLiteral() {
259                         // The error has a pattern has a pattern similar to the import path.
260                         // It may be slightly different (./foo matching example.com/foo),
261                         // but close enough to seem redundant.
262                         // Unwrap the error so we don't show the pattern.
263                         err = matchErr.Err
264                 }
265         }
266
267         // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.
268         // The latter is more specific about the cause.
269         var nogoErr *build.NoGoError
270         if errors.As(err, &nogoErr) {
271                 if p.Dir == "" && nogoErr.Dir != "" {
272                         p.Dir = nogoErr.Dir
273                 }
274                 err = &NoGoError{Package: p}
275         }
276
277         // Take only the first error from a scanner.ErrorList. PackageError only
278         // has room for one position, so we report the first error with a position
279         // instead of all of the errors without a position.
280         var pos string
281         var isScanErr bool
282         if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
283                 isScanErr = true // For stack push/pop below.
284
285                 scanPos := scanErr[0].Pos
286                 scanPos.Filename = base.ShortPath(scanPos.Filename)
287                 pos = scanPos.String()
288                 err = errors.New(scanErr[0].Msg)
289         }
290
291         // Report the error on the importing package if the problem is with the import declaration
292         // for example, if the package doesn't exist or if the import path is malformed.
293         // On the other hand, don't include a position if the problem is with the imported package,
294         // for example there are no Go files (NoGoError), or there's a problem in the imported
295         // package's source files themselves (scanner errors).
296         //
297         // TODO(matloob): Perhaps make each of those the errors in the first group
298         // (including modload.ImportMissingError, ImportMissingSumError, and the
299         // corresponding "cannot find package %q in any of" GOPATH-mode error
300         // produced in build.(*Context).Import; modload.AmbiguousImportError,
301         // and modload.PackageNotInModuleError; and the malformed module path errors
302         // produced in golang.org/x/mod/module.CheckMod) implement an interface
303         // to make it easier to check for them? That would save us from having to
304         // move the modload errors into this package to avoid a package import cycle,
305         // and from having to export an error type for the errors produced in build.
306         if !isMatchErr && (nogoErr != nil || isScanErr) {
307                 stk.Push(path)
308                 defer stk.Pop()
309         }
310
311         p.Error = &PackageError{
312                 ImportStack: stk.Copy(),
313                 Pos:         pos,
314                 Err:         err,
315         }
316
317         if path != stk.Top() {
318                 p.Error.setPos(importPos)
319         }
320 }
321
322 // Resolve returns the resolved version of imports,
323 // which should be p.TestImports or p.XTestImports, NOT p.Imports.
324 // The imports in p.TestImports and p.XTestImports are not recursively
325 // loaded during the initial load of p, so they list the imports found in
326 // the source file, but most processing should be over the vendor-resolved
327 // import paths. We do this resolution lazily both to avoid file system work
328 // and because the eventual real load of the test imports (during 'go test')
329 // can produce better error messages if it starts with the original paths.
330 // The initial load of p loads all the non-test imports and rewrites
331 // the vendored paths, so nothing should ever call p.vendored(p.Imports).
332 func (p *Package) Resolve(imports []string) []string {
333         if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
334                 panic("internal error: p.Resolve(p.Imports) called")
335         }
336         seen := make(map[string]bool)
337         var all []string
338         for _, path := range imports {
339                 path = ResolveImportPath(p, path)
340                 if !seen[path] {
341                         seen[path] = true
342                         all = append(all, path)
343                 }
344         }
345         sort.Strings(all)
346         return all
347 }
348
349 // CoverVar holds the name of the generated coverage variables targeting the named file.
350 type CoverVar struct {
351         File string // local file name
352         Var  string // name of count struct
353 }
354
355 func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {
356         p.Internal.Build = pp
357
358         if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
359                 old := pp.PkgTargetRoot
360                 pp.PkgRoot = cfg.BuildPkgdir
361                 pp.PkgTargetRoot = cfg.BuildPkgdir
362                 pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
363         }
364
365         p.Dir = pp.Dir
366         p.ImportPath = pp.ImportPath
367         p.ImportComment = pp.ImportComment
368         p.Name = pp.Name
369         p.Doc = pp.Doc
370         p.Root = pp.Root
371         p.ConflictDir = pp.ConflictDir
372         p.BinaryOnly = pp.BinaryOnly
373
374         // TODO? Target
375         p.Goroot = pp.Goroot
376         p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)
377         p.GoFiles = pp.GoFiles
378         p.CgoFiles = pp.CgoFiles
379         p.IgnoredGoFiles = pp.IgnoredGoFiles
380         p.InvalidGoFiles = pp.InvalidGoFiles
381         p.IgnoredOtherFiles = pp.IgnoredOtherFiles
382         p.CFiles = pp.CFiles
383         p.CXXFiles = pp.CXXFiles
384         p.MFiles = pp.MFiles
385         p.HFiles = pp.HFiles
386         p.FFiles = pp.FFiles
387         p.SFiles = pp.SFiles
388         p.SwigFiles = pp.SwigFiles
389         p.SwigCXXFiles = pp.SwigCXXFiles
390         p.SysoFiles = pp.SysoFiles
391         if cfg.BuildMSan {
392                 // There's no way for .syso files to be built both with and without
393                 // support for memory sanitizer. Assume they are built without,
394                 // and drop them.
395                 p.SysoFiles = nil
396         }
397         p.CgoCFLAGS = pp.CgoCFLAGS
398         p.CgoCPPFLAGS = pp.CgoCPPFLAGS
399         p.CgoCXXFLAGS = pp.CgoCXXFLAGS
400         p.CgoFFLAGS = pp.CgoFFLAGS
401         p.CgoLDFLAGS = pp.CgoLDFLAGS
402         p.CgoPkgConfig = pp.CgoPkgConfig
403         // We modify p.Imports in place, so make copy now.
404         p.Imports = make([]string, len(pp.Imports))
405         copy(p.Imports, pp.Imports)
406         p.Internal.RawImports = pp.Imports
407         p.TestGoFiles = pp.TestGoFiles
408         p.TestImports = pp.TestImports
409         p.XTestGoFiles = pp.XTestGoFiles
410         p.XTestImports = pp.XTestImports
411         if opts.IgnoreImports {
412                 p.Imports = nil
413                 p.Internal.RawImports = nil
414                 p.TestImports = nil
415                 p.XTestImports = nil
416         }
417         p.EmbedPatterns = pp.EmbedPatterns
418         p.TestEmbedPatterns = pp.TestEmbedPatterns
419         p.XTestEmbedPatterns = pp.XTestEmbedPatterns
420         p.Internal.OrigImportPath = pp.ImportPath
421 }
422
423 // A PackageError describes an error loading information about a package.
424 type PackageError struct {
425         ImportStack      []string // shortest path from package named on command line to this one
426         Pos              string   // position of error
427         Err              error    // the error itself
428         IsImportCycle    bool     // the error is an import cycle
429         Hard             bool     // whether the error is soft or hard; soft errors are ignored in some places
430         alwaysPrintStack bool     // whether to always print the ImportStack
431 }
432
433 func (p *PackageError) Error() string {
434         // TODO(#43696): decide when to print the stack or the position based on
435         // the error type and whether the package is in the main module.
436         // Document the rationale.
437         if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
438                 // Omit import stack. The full path to the file where the error
439                 // is the most important thing.
440                 return p.Pos + ": " + p.Err.Error()
441         }
442
443         // If the error is an ImportPathError, and the last path on the stack appears
444         // in the error message, omit that path from the stack to avoid repetition.
445         // If an ImportPathError wraps another ImportPathError that matches the
446         // last path on the stack, we don't omit the path. An error like
447         // "package A imports B: error loading C caused by B" would not be clearer
448         // if "imports B" were omitted.
449         if len(p.ImportStack) == 0 {
450                 return p.Err.Error()
451         }
452         var optpos string
453         if p.Pos != "" {
454                 optpos = "\n\t" + p.Pos
455         }
456         return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error()
457 }
458
459 func (p *PackageError) Unwrap() error { return p.Err }
460
461 // PackageError implements MarshalJSON so that Err is marshaled as a string
462 // and non-essential fields are omitted.
463 func (p *PackageError) MarshalJSON() ([]byte, error) {
464         perr := struct {
465                 ImportStack []string
466                 Pos         string
467                 Err         string
468         }{p.ImportStack, p.Pos, p.Err.Error()}
469         return json.Marshal(perr)
470 }
471
472 func (p *PackageError) setPos(posList []token.Position) {
473         if len(posList) == 0 {
474                 return
475         }
476         pos := posList[0]
477         pos.Filename = base.ShortPath(pos.Filename)
478         p.Pos = pos.String()
479 }
480
481 // ImportPathError is a type of error that prevents a package from being loaded
482 // for a given import path. When such a package is loaded, a *Package is
483 // returned with Err wrapping an ImportPathError: the error is attached to
484 // the imported package, not the importing package.
485 //
486 // The string returned by ImportPath must appear in the string returned by
487 // Error. Errors that wrap ImportPathError (such as PackageError) may omit
488 // the import path.
489 type ImportPathError interface {
490         error
491         ImportPath() string
492 }
493
494 var (
495         _ ImportPathError = (*importError)(nil)
496         _ ImportPathError = (*mainPackageError)(nil)
497         _ ImportPathError = (*modload.ImportMissingError)(nil)
498         _ ImportPathError = (*modload.ImportMissingSumError)(nil)
499         _ ImportPathError = (*modload.DirectImportFromImplicitDependencyError)(nil)
500 )
501
502 type importError struct {
503         importPath string
504         err        error // created with fmt.Errorf
505 }
506
507 func ImportErrorf(path, format string, args ...any) ImportPathError {
508         err := &importError{importPath: path, err: fmt.Errorf(format, args...)}
509         if errStr := err.Error(); !strings.Contains(errStr, path) {
510                 panic(fmt.Sprintf("path %q not in error %q", path, errStr))
511         }
512         return err
513 }
514
515 func (e *importError) Error() string {
516         return e.err.Error()
517 }
518
519 func (e *importError) Unwrap() error {
520         // Don't return e.err directly, since we're only wrapping an error if %w
521         // was passed to ImportErrorf.
522         return errors.Unwrap(e.err)
523 }
524
525 func (e *importError) ImportPath() string {
526         return e.importPath
527 }
528
529 // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.
530 // The import path of a test package is the import path of the corresponding
531 // non-test package with the suffix "_test" added.
532 type ImportStack []string
533
534 func (s *ImportStack) Push(p string) {
535         *s = append(*s, p)
536 }
537
538 func (s *ImportStack) Pop() {
539         *s = (*s)[0 : len(*s)-1]
540 }
541
542 func (s *ImportStack) Copy() []string {
543         return append([]string{}, *s...)
544 }
545
546 func (s *ImportStack) Top() string {
547         if len(*s) == 0 {
548                 return ""
549         }
550         return (*s)[len(*s)-1]
551 }
552
553 // shorterThan reports whether sp is shorter than t.
554 // We use this to record the shortest import sequence
555 // that leads to a particular package.
556 func (sp *ImportStack) shorterThan(t []string) bool {
557         s := *sp
558         if len(s) != len(t) {
559                 return len(s) < len(t)
560         }
561         // If they are the same length, settle ties using string ordering.
562         for i := range s {
563                 if s[i] != t[i] {
564                         return s[i] < t[i]
565                 }
566         }
567         return false // they are equal
568 }
569
570 // packageCache is a lookup cache for LoadImport,
571 // so that if we look up a package multiple times
572 // we return the same pointer each time.
573 var packageCache = map[string]*Package{}
574
575 // ClearPackageCache clears the in-memory package cache and the preload caches.
576 // It is only for use by GOPATH-based "go get".
577 // TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
578 func ClearPackageCache() {
579         for name := range packageCache {
580                 delete(packageCache, name)
581         }
582         resolvedImportCache.Clear()
583         packageDataCache.Clear()
584 }
585
586 // ClearPackageCachePartial clears packages with the given import paths from the
587 // in-memory package cache and the preload caches. It is only for use by
588 // GOPATH-based "go get".
589 // TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
590 func ClearPackageCachePartial(args []string) {
591         shouldDelete := make(map[string]bool)
592         for _, arg := range args {
593                 shouldDelete[arg] = true
594                 if p := packageCache[arg]; p != nil {
595                         delete(packageCache, arg)
596                 }
597         }
598         resolvedImportCache.DeleteIf(func(key any) bool {
599                 return shouldDelete[key.(importSpec).path]
600         })
601         packageDataCache.DeleteIf(func(key any) bool {
602                 return shouldDelete[key.(string)]
603         })
604 }
605
606 // ReloadPackageNoFlags is like LoadImport but makes sure
607 // not to use the package cache.
608 // It is only for use by GOPATH-based "go get".
609 // TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
610 func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
611         p := packageCache[arg]
612         if p != nil {
613                 delete(packageCache, arg)
614                 resolvedImportCache.DeleteIf(func(key any) bool {
615                         return key.(importSpec).path == p.ImportPath
616                 })
617                 packageDataCache.Delete(p.ImportPath)
618         }
619         return LoadImport(context.TODO(), PackageOpts{}, arg, base.Cwd(), nil, stk, nil, 0)
620 }
621
622 // dirToImportPath returns the pseudo-import path we use for a package
623 // outside the Go path. It begins with _/ and then contains the full path
624 // to the directory. If the package lives in c:\home\gopher\my\pkg then
625 // the pseudo-import path is _/c_/home/gopher/my/pkg.
626 // Using a pseudo-import path like this makes the ./ imports no longer
627 // a special case, so that all the code to deal with ordinary imports works
628 // automatically.
629 func dirToImportPath(dir string) string {
630         return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
631 }
632
633 func makeImportValid(r rune) rune {
634         // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
635         const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
636         if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
637                 return '_'
638         }
639         return r
640 }
641
642 // Mode flags for loadImport and download (in get.go).
643 const (
644         // ResolveImport means that loadImport should do import path expansion.
645         // That is, ResolveImport means that the import path came from
646         // a source file and has not been expanded yet to account for
647         // vendoring or possible module adjustment.
648         // Every import path should be loaded initially with ResolveImport,
649         // and then the expanded version (for example with the /vendor/ in it)
650         // gets recorded as the canonical import path. At that point, future loads
651         // of that package must not pass ResolveImport, because
652         // disallowVendor will reject direct use of paths containing /vendor/.
653         ResolveImport = 1 << iota
654
655         // ResolveModule is for download (part of "go get") and indicates
656         // that the module adjustment should be done, but not vendor adjustment.
657         ResolveModule
658
659         // GetTestDeps is for download (part of "go get") and indicates
660         // that test dependencies should be fetched too.
661         GetTestDeps
662 )
663
664 // LoadImport scans the directory named by path, which must be an import path,
665 // but possibly a local import path (an absolute file system path or one beginning
666 // with ./ or ../). A local relative path is interpreted relative to srcDir.
667 // It returns a *Package describing the package found in that directory.
668 // LoadImport does not set tool flags and should only be used by
669 // this package, as part of a bigger load operation, and by GOPATH-based "go get".
670 // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
671 func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
672         return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
673 }
674
675 func loadImport(ctx context.Context, opts PackageOpts, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
676         if path == "" {
677                 panic("LoadImport called with empty package path")
678         }
679
680         var parentPath, parentRoot string
681         parentIsStd := false
682         if parent != nil {
683                 parentPath = parent.ImportPath
684                 parentRoot = parent.Root
685                 parentIsStd = parent.Standard
686         }
687         bp, loaded, err := loadPackageData(ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)
688         if loaded && pre != nil && !opts.IgnoreImports {
689                 pre.preloadImports(ctx, opts, bp.Imports, bp)
690         }
691         if bp == nil {
692                 p := &Package{
693                         PackagePublic: PackagePublic{
694                                 ImportPath: path,
695                                 Incomplete: true,
696                         },
697                 }
698                 if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
699                         // Only add path to the error's import stack if it's not already present
700                         // in the error.
701                         //
702                         // TODO(bcmills): setLoadPackageDataError itself has a similar Push / Pop
703                         // sequence that empirically doesn't trigger for these errors, guarded by
704                         // a somewhat complex condition. Figure out how to generalize that
705                         // condition and eliminate the explicit calls here.
706                         stk.Push(path)
707                         defer stk.Pop()
708                 }
709                 p.setLoadPackageDataError(err, path, stk, nil)
710                 return p
711         }
712
713         importPath := bp.ImportPath
714         p := packageCache[importPath]
715         if p != nil {
716                 stk.Push(path)
717                 p = reusePackage(p, stk)
718                 stk.Pop()
719         } else {
720                 p = new(Package)
721                 p.Internal.Local = build.IsLocalImport(path)
722                 p.ImportPath = importPath
723                 packageCache[importPath] = p
724
725                 // Load package.
726                 // loadPackageData may return bp != nil even if an error occurs,
727                 // in order to return partial information.
728                 p.load(ctx, opts, path, stk, importPos, bp, err)
729
730                 if !cfg.ModulesEnabled && path != cleanImport(path) {
731                         p.Error = &PackageError{
732                                 ImportStack: stk.Copy(),
733                                 Err:         ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
734                         }
735                         p.Incomplete = true
736                         p.Error.setPos(importPos)
737                 }
738         }
739
740         // Checked on every import because the rules depend on the code doing the importing.
741         if perr := disallowInternal(ctx, srcDir, parent, parentPath, p, stk); perr != p {
742                 perr.Error.setPos(importPos)
743                 return perr
744         }
745         if mode&ResolveImport != 0 {
746                 if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p {
747                         perr.Error.setPos(importPos)
748                         return perr
749                 }
750         }
751
752         if p.Name == "main" && parent != nil && parent.Dir != p.Dir {
753                 perr := *p
754                 perr.Error = &PackageError{
755                         ImportStack: stk.Copy(),
756                         Err:         ImportErrorf(path, "import %q is a program, not an importable package", path),
757                 }
758                 perr.Error.setPos(importPos)
759                 return &perr
760         }
761
762         if p.Internal.Local && parent != nil && !parent.Internal.Local {
763                 perr := *p
764                 var err error
765                 if path == "." {
766                         err = ImportErrorf(path, "%s: cannot import current directory", path)
767                 } else {
768                         err = ImportErrorf(path, "local import %q in non-local package", path)
769                 }
770                 perr.Error = &PackageError{
771                         ImportStack: stk.Copy(),
772                         Err:         err,
773                 }
774                 perr.Error.setPos(importPos)
775                 return &perr
776         }
777
778         return p
779 }
780
781 // loadPackageData loads information needed to construct a *Package. The result
782 // is cached, and later calls to loadPackageData for the same package will return
783 // the same data.
784 //
785 // loadPackageData returns a non-nil package even if err is non-nil unless
786 // the package path is malformed (for example, the path contains "mod/" or "@").
787 //
788 // loadPackageData returns a boolean, loaded, which is true if this is the
789 // first time the package was loaded. Callers may preload imports in this case.
790 func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
791         if path == "" {
792                 panic("loadPackageData called with empty package path")
793         }
794
795         if strings.HasPrefix(path, "mod/") {
796                 // Paths beginning with "mod/" might accidentally
797                 // look in the module cache directory tree in $GOPATH/pkg/mod/.
798                 // This prefix is owned by the Go core for possible use in the
799                 // standard library (since it does not begin with a domain name),
800                 // so it's OK to disallow entirely.
801                 return nil, false, fmt.Errorf("disallowed import path %q", path)
802         }
803
804         if strings.Contains(path, "@") {
805                 return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
806         }
807
808         // Determine canonical package path and directory.
809         // For a local import the identifier is the pseudo-import path
810         // we create from the full directory to the package.
811         // Otherwise it is the usual import path.
812         // For vendored imports, it is the expanded form.
813         //
814         // Note that when modules are enabled, local import paths are normally
815         // canonicalized by modload.LoadPackages before now. However, if there's an
816         // error resolving a local path, it will be returned untransformed
817         // so that 'go list -e' reports something useful.
818         importKey := importSpec{
819                 path:        path,
820                 parentPath:  parentPath,
821                 parentDir:   parentDir,
822                 parentRoot:  parentRoot,
823                 parentIsStd: parentIsStd,
824                 mode:        mode,
825         }
826         r := resolvedImportCache.Do(importKey, func() any {
827                 var r resolvedImport
828                 if build.IsLocalImport(path) {
829                         r.dir = filepath.Join(parentDir, path)
830                         r.path = dirToImportPath(r.dir)
831                 } else if cfg.ModulesEnabled {
832                         r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path)
833                 } else if mode&ResolveImport != 0 {
834                         // We do our own path resolution, because we want to
835                         // find out the key to use in packageCache without the
836                         // overhead of repeated calls to buildContext.Import.
837                         // The code is also needed in a few other places anyway.
838                         r.path = resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
839                 } else if mode&ResolveModule != 0 {
840                         r.path = moduleImportPath(path, parentPath, parentDir, parentRoot)
841                 }
842                 if r.path == "" {
843                         r.path = path
844                 }
845                 return r
846         }).(resolvedImport)
847         // Invariant: r.path is set to the resolved import path. If the path cannot
848         // be resolved, r.path is set to path, the source import path.
849         // r.path is never empty.
850
851         // Load the package from its directory. If we already found the package's
852         // directory when resolving its import path, use that.
853         data := packageDataCache.Do(r.path, func() any {
854                 loaded = true
855                 var data packageData
856                 if r.dir != "" {
857                         var buildMode build.ImportMode
858                         if !cfg.ModulesEnabled {
859                                 buildMode = build.ImportComment
860                         }
861                         data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
862                         if cfg.ModulesEnabled {
863                                 // Override data.p.Root, since ImportDir sets it to $GOPATH, if
864                                 // the module is inside $GOPATH/src.
865                                 if info := modload.PackageModuleInfo(ctx, path); info != nil {
866                                         data.p.Root = info.Dir
867                                 }
868                         }
869                         if r.err != nil {
870                                 if data.err != nil {
871                                         // ImportDir gave us one error, and the module loader gave us another.
872                                         // We arbitrarily choose to keep the error from ImportDir because
873                                         // that's what our tests already expect, and it seems to provide a bit
874                                         // more detail in most cases.
875                                 } else if errors.Is(r.err, imports.ErrNoGo) {
876                                         // ImportDir said there were files in the package, but the module
877                                         // loader said there weren't. Which one is right?
878                                         // Without this special-case hack, the TestScript/test_vet case fails
879                                         // on the vetfail/p1 package (added in CL 83955).
880                                         // Apparently, imports.ShouldBuild biases toward rejecting files
881                                         // with invalid build constraints, whereas ImportDir biases toward
882                                         // accepting them.
883                                         //
884                                         // TODO(#41410: Figure out how this actually ought to work and fix
885                                         // this mess.
886                                 } else {
887                                         data.err = r.err
888                                 }
889                         }
890                 } else if r.err != nil {
891                         data.p = new(build.Package)
892                         data.err = r.err
893                 } else if cfg.ModulesEnabled && path != "unsafe" {
894                         data.p = new(build.Package)
895                         data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)
896                 } else {
897                         buildMode := build.ImportComment
898                         if mode&ResolveImport == 0 || r.path != path {
899                                 // Not vendoring, or we already found the vendored path.
900                                 buildMode |= build.IgnoreVendor
901                         }
902                         data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode)
903                 }
904                 data.p.ImportPath = r.path
905
906                 // Set data.p.BinDir in cases where go/build.Context.Import
907                 // may give us a path we don't want.
908                 if !data.p.Goroot {
909                         if cfg.GOBIN != "" {
910                                 data.p.BinDir = cfg.GOBIN
911                         } else if cfg.ModulesEnabled {
912                                 data.p.BinDir = modload.BinDir()
913                         }
914                 }
915
916                 if !cfg.ModulesEnabled && data.err == nil &&
917                         data.p.ImportComment != "" && data.p.ImportComment != path &&
918                         !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
919                         data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment)
920                 }
921                 return data
922         }).(packageData)
923
924         return data.p, loaded, data.err
925 }
926
927 // importSpec describes an import declaration in source code. It is used as a
928 // cache key for resolvedImportCache.
929 type importSpec struct {
930         path                              string
931         parentPath, parentDir, parentRoot string
932         parentIsStd                       bool
933         mode                              int
934 }
935
936 // resolvedImport holds a canonical identifier for a package. It may also contain
937 // a path to the package's directory and an error if one occurred. resolvedImport
938 // is the value type in resolvedImportCache.
939 type resolvedImport struct {
940         path, dir string
941         err       error
942 }
943
944 // packageData holds information loaded from a package. It is the value type
945 // in packageDataCache.
946 type packageData struct {
947         p   *build.Package
948         err error
949 }
950
951 // resolvedImportCache maps import strings (importSpec) to canonical package names
952 // (resolvedImport).
953 var resolvedImportCache par.Cache
954
955 // packageDataCache maps canonical package names (string) to package metadata
956 // (packageData).
957 var packageDataCache par.Cache
958
959 // preloadWorkerCount is the number of concurrent goroutines that can load
960 // packages. Experimentally, there are diminishing returns with more than
961 // 4 workers. This was measured on the following machines.
962 //
963 // * MacBookPro with a 4-core Intel Core i7 CPU
964 // * Linux workstation with 6-core Intel Xeon CPU
965 // * Linux workstation with 24-core Intel Xeon CPU
966 //
967 // It is very likely (though not confirmed) that this workload is limited
968 // by memory bandwidth. We don't have a good way to determine the number of
969 // workers that would saturate the bus though, so runtime.GOMAXPROCS
970 // seems like a reasonable default.
971 var preloadWorkerCount = runtime.GOMAXPROCS(0)
972
973 // preload holds state for managing concurrent preloading of package data.
974 //
975 // A preload should be created with newPreload before loading a large
976 // package graph. flush must be called when package loading is complete
977 // to ensure preload goroutines are no longer active. This is necessary
978 // because of global mutable state that cannot safely be read and written
979 // concurrently. In particular, packageDataCache may be cleared by "go get"
980 // in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be
981 // modified by modload.LoadPackages.
982 type preload struct {
983         cancel chan struct{}
984         sema   chan struct{}
985 }
986
987 // newPreload creates a new preloader. flush must be called later to avoid
988 // accessing global state while it is being modified.
989 func newPreload() *preload {
990         pre := &preload{
991                 cancel: make(chan struct{}),
992                 sema:   make(chan struct{}, preloadWorkerCount),
993         }
994         return pre
995 }
996
997 // preloadMatches loads data for package paths matched by patterns.
998 // When preloadMatches returns, some packages may not be loaded yet, but
999 // loadPackageData and loadImport are always safe to call.
1000 func (pre *preload) preloadMatches(ctx context.Context, opts PackageOpts, matches []*search.Match) {
1001         for _, m := range matches {
1002                 for _, pkg := range m.Pkgs {
1003                         select {
1004                         case <-pre.cancel:
1005                                 return
1006                         case pre.sema <- struct{}{}:
1007                                 go func(pkg string) {
1008                                         mode := 0 // don't use vendoring or module import resolution
1009                                         bp, loaded, err := loadPackageData(ctx, pkg, "", base.Cwd(), "", false, mode)
1010                                         <-pre.sema
1011                                         if bp != nil && loaded && err == nil && !opts.IgnoreImports {
1012                                                 pre.preloadImports(ctx, opts, bp.Imports, bp)
1013                                         }
1014                                 }(pkg)
1015                         }
1016                 }
1017         }
1018 }
1019
1020 // preloadImports queues a list of imports for preloading.
1021 // When preloadImports returns, some packages may not be loaded yet,
1022 // but loadPackageData and loadImport are always safe to call.
1023 func (pre *preload) preloadImports(ctx context.Context, opts PackageOpts, imports []string, parent *build.Package) {
1024         parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)
1025         for _, path := range imports {
1026                 if path == "C" || path == "unsafe" {
1027                         continue
1028                 }
1029                 select {
1030                 case <-pre.cancel:
1031                         return
1032                 case pre.sema <- struct{}{}:
1033                         go func(path string) {
1034                                 bp, loaded, err := loadPackageData(ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
1035                                 <-pre.sema
1036                                 if bp != nil && loaded && err == nil && !opts.IgnoreImports {
1037                                         pre.preloadImports(ctx, opts, bp.Imports, bp)
1038                                 }
1039                         }(path)
1040                 }
1041         }
1042 }
1043
1044 // flush stops pending preload operations. flush blocks until preload calls to
1045 // loadPackageData have completed. The preloader will not make any new calls
1046 // to loadPackageData.
1047 func (pre *preload) flush() {
1048         // flush is usually deferred.
1049         // Don't hang program waiting for workers on panic.
1050         if v := recover(); v != nil {
1051                 panic(v)
1052         }
1053
1054         close(pre.cancel)
1055         for i := 0; i < preloadWorkerCount; i++ {
1056                 pre.sema <- struct{}{}
1057         }
1058 }
1059
1060 func cleanImport(path string) string {
1061         orig := path
1062         path = pathpkg.Clean(path)
1063         if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
1064                 path = "./" + path
1065         }
1066         return path
1067 }
1068
1069 var isDirCache par.Cache
1070
1071 func isDir(path string) bool {
1072         return isDirCache.Do(path, func() any {
1073                 fi, err := fsys.Stat(path)
1074                 return err == nil && fi.IsDir()
1075         }).(bool)
1076 }
1077
1078 // ResolveImportPath returns the true meaning of path when it appears in parent.
1079 // There are two different resolutions applied.
1080 // First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
1081 // If vendor expansion doesn't trigger, then the path is also subject to
1082 // Go 1.11 module legacy conversion (golang.org/issue/25069).
1083 func ResolveImportPath(parent *Package, path string) (found string) {
1084         var parentPath, parentDir, parentRoot string
1085         parentIsStd := false
1086         if parent != nil {
1087                 parentPath = parent.ImportPath
1088                 parentDir = parent.Dir
1089                 parentRoot = parent.Root
1090                 parentIsStd = parent.Standard
1091         }
1092         return resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
1093 }
1094
1095 func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
1096         if cfg.ModulesEnabled {
1097                 if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil {
1098                         return p
1099                 }
1100                 return path
1101         }
1102         found = vendoredImportPath(path, parentPath, parentDir, parentRoot)
1103         if found != path {
1104                 return found
1105         }
1106         return moduleImportPath(path, parentPath, parentDir, parentRoot)
1107 }
1108
1109 // dirAndRoot returns the source directory and workspace root
1110 // for the package p, guaranteeing that root is a path prefix of dir.
1111 func dirAndRoot(path string, dir, root string) (string, string) {
1112         origDir, origRoot := dir, root
1113         dir = filepath.Clean(dir)
1114         root = filepath.Join(root, "src")
1115         if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir {
1116                 // Look for symlinks before reporting error.
1117                 dir = expandPath(dir)
1118                 root = expandPath(root)
1119         }
1120
1121         if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || path != "command-line-arguments" && !build.IsLocalImport(path) && filepath.Join(root, path) != dir {
1122                 base.Fatalf("unexpected directory layout:\n"+
1123                         "       import path: %s\n"+
1124                         "       root: %s\n"+
1125                         "       dir: %s\n"+
1126                         "       expand root: %s\n"+
1127                         "       expand dir: %s\n"+
1128                         "       separator: %s",
1129                         path,
1130                         filepath.Join(origRoot, "src"),
1131                         filepath.Clean(origDir),
1132                         origRoot,
1133                         origDir,
1134                         string(filepath.Separator))
1135         }
1136
1137         return dir, root
1138 }
1139
1140 // vendoredImportPath returns the vendor-expansion of path when it appears in parent.
1141 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
1142 // x/vendor/path, vendor/path, or else stay path if none of those exist.
1143 // vendoredImportPath returns the expanded path or, if no expansion is found, the original.
1144 func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1145         if parentRoot == "" {
1146                 return path
1147         }
1148
1149         dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1150
1151         vpath := "vendor/" + path
1152         for i := len(dir); i >= len(root); i-- {
1153                 if i < len(dir) && dir[i] != filepath.Separator {
1154                         continue
1155                 }
1156                 // Note: checking for the vendor directory before checking
1157                 // for the vendor/path directory helps us hit the
1158                 // isDir cache more often. It also helps us prepare a more useful
1159                 // list of places we looked, to report when an import is not found.
1160                 if !isDir(filepath.Join(dir[:i], "vendor")) {
1161                         continue
1162                 }
1163                 targ := filepath.Join(dir[:i], vpath)
1164                 if isDir(targ) && hasGoFiles(targ) {
1165                         importPath := parentPath
1166                         if importPath == "command-line-arguments" {
1167                                 // If parent.ImportPath is 'command-line-arguments'.
1168                                 // set to relative directory to root (also chopped root directory)
1169                                 importPath = dir[len(root)+1:]
1170                         }
1171                         // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
1172                         // We know the import path for parent's dir.
1173                         // We chopped off some number of path elements and
1174                         // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
1175                         // Now we want to know the import path for that directory.
1176                         // Construct it by chopping the same number of path elements
1177                         // (actually the same number of bytes) from parent's import path
1178                         // and then append /vendor/path.
1179                         chopped := len(dir) - i
1180                         if chopped == len(importPath)+1 {
1181                                 // We walked up from c:\gopath\src\foo\bar
1182                                 // and found c:\gopath\src\vendor\path.
1183                                 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
1184                                 // Use "vendor/path" without any prefix.
1185                                 return vpath
1186                         }
1187                         return importPath[:len(importPath)-chopped] + "/" + vpath
1188                 }
1189         }
1190         return path
1191 }
1192
1193 var (
1194         modulePrefix   = []byte("\nmodule ")
1195         goModPathCache par.Cache
1196 )
1197
1198 // goModPath returns the module path in the go.mod in dir, if any.
1199 func goModPath(dir string) (path string) {
1200         return goModPathCache.Do(dir, func() any {
1201                 data, err := os.ReadFile(filepath.Join(dir, "go.mod"))
1202                 if err != nil {
1203                         return ""
1204                 }
1205                 var i int
1206                 if bytes.HasPrefix(data, modulePrefix[1:]) {
1207                         i = 0
1208                 } else {
1209                         i = bytes.Index(data, modulePrefix)
1210                         if i < 0 {
1211                                 return ""
1212                         }
1213                         i++
1214                 }
1215                 line := data[i:]
1216
1217                 // Cut line at \n, drop trailing \r if present.
1218                 if j := bytes.IndexByte(line, '\n'); j >= 0 {
1219                         line = line[:j]
1220                 }
1221                 if line[len(line)-1] == '\r' {
1222                         line = line[:len(line)-1]
1223                 }
1224                 line = line[len("module "):]
1225
1226                 // If quoted, unquote.
1227                 path = strings.TrimSpace(string(line))
1228                 if path != "" && path[0] == '"' {
1229                         s, err := strconv.Unquote(path)
1230                         if err != nil {
1231                                 return ""
1232                         }
1233                         path = s
1234                 }
1235                 return path
1236         }).(string)
1237 }
1238
1239 // findVersionElement returns the slice indices of the final version element /vN in path.
1240 // If there is no such element, it returns -1, -1.
1241 func findVersionElement(path string) (i, j int) {
1242         j = len(path)
1243         for i = len(path) - 1; i >= 0; i-- {
1244                 if path[i] == '/' {
1245                         if isVersionElement(path[i+1 : j]) {
1246                                 return i, j
1247                         }
1248                         j = i
1249                 }
1250         }
1251         return -1, -1
1252 }
1253
1254 // isVersionElement reports whether s is a well-formed path version element:
1255 // v2, v3, v10, etc, but not v0, v05, v1.
1256 func isVersionElement(s string) bool {
1257         if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 {
1258                 return false
1259         }
1260         for i := 1; i < len(s); i++ {
1261                 if s[i] < '0' || '9' < s[i] {
1262                         return false
1263                 }
1264         }
1265         return true
1266 }
1267
1268 // moduleImportPath translates import paths found in go modules
1269 // back down to paths that can be resolved in ordinary builds.
1270 //
1271 // Define “new” code as code with a go.mod file in the same directory
1272 // or a parent directory. If an import in new code says x/y/v2/z but
1273 // x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,
1274 // then go build will read the import as x/y/z instead.
1275 // See golang.org/issue/25069.
1276 func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1277         if parentRoot == "" {
1278                 return path
1279         }
1280
1281         // If there are no vN elements in path, leave it alone.
1282         // (The code below would do the same, but only after
1283         // some other file system accesses that we can avoid
1284         // here by returning early.)
1285         if i, _ := findVersionElement(path); i < 0 {
1286                 return path
1287         }
1288
1289         dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1290
1291         // Consider dir and parents, up to and including root.
1292         for i := len(dir); i >= len(root); i-- {
1293                 if i < len(dir) && dir[i] != filepath.Separator {
1294                         continue
1295                 }
1296                 if goModPath(dir[:i]) != "" {
1297                         goto HaveGoMod
1298                 }
1299         }
1300         // This code is not in a tree with a go.mod,
1301         // so apply no changes to the path.
1302         return path
1303
1304 HaveGoMod:
1305         // This import is in a tree with a go.mod.
1306         // Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z
1307         // if GOPATH/src/x/y/go.mod says module "x/y/v2",
1308
1309         // If x/y/v2/z exists, use it unmodified.
1310         if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {
1311                 return path
1312         }
1313
1314         // Otherwise look for a go.mod supplying a version element.
1315         // Some version-like elements may appear in paths but not
1316         // be module versions; we skip over those to look for module
1317         // versions. For example the module m/v2 might have a
1318         // package m/v2/api/v1/foo.
1319         limit := len(path)
1320         for limit > 0 {
1321                 i, j := findVersionElement(path[:limit])
1322                 if i < 0 {
1323                         return path
1324                 }
1325                 if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {
1326                         if mpath := goModPath(bp.Dir); mpath != "" {
1327                                 // Found a valid go.mod file, so we're stopping the search.
1328                                 // If the path is m/v2/p and we found m/go.mod that says
1329                                 // "module m/v2", then we return "m/p".
1330                                 if mpath == path[:j] {
1331                                         return path[:i] + path[j:]
1332                                 }
1333                                 // Otherwise just return the original path.
1334                                 // We didn't find anything worth rewriting,
1335                                 // and the go.mod indicates that we should
1336                                 // not consider parent directories.
1337                                 return path
1338                         }
1339                 }
1340                 limit = i
1341         }
1342         return path
1343 }
1344
1345 // hasGoFiles reports whether dir contains any files with names ending in .go.
1346 // For a vendor check we must exclude directories that contain no .go files.
1347 // Otherwise it is not possible to vendor just a/b/c and still import the
1348 // non-vendored a/b. See golang.org/issue/13832.
1349 func hasGoFiles(dir string) bool {
1350         files, _ := os.ReadDir(dir)
1351         for _, f := range files {
1352                 if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
1353                         return true
1354                 }
1355         }
1356         return false
1357 }
1358
1359 // reusePackage reuses package p to satisfy the import at the top
1360 // of the import stack stk. If this use causes an import loop,
1361 // reusePackage updates p's error information to record the loop.
1362 func reusePackage(p *Package, stk *ImportStack) *Package {
1363         // We use p.Internal.Imports==nil to detect a package that
1364         // is in the midst of its own loadPackage call
1365         // (all the recursion below happens before p.Internal.Imports gets set).
1366         if p.Internal.Imports == nil {
1367                 if p.Error == nil {
1368                         p.Error = &PackageError{
1369                                 ImportStack:   stk.Copy(),
1370                                 Err:           errors.New("import cycle not allowed"),
1371                                 IsImportCycle: true,
1372                         }
1373                 } else if !p.Error.IsImportCycle {
1374                         // If the error is already set, but it does not indicate that
1375                         // we are in an import cycle, set IsImportCycle so that we don't
1376                         // end up stuck in a loop down the road.
1377                         p.Error.IsImportCycle = true
1378                 }
1379                 p.Incomplete = true
1380         }
1381         // Don't rewrite the import stack in the error if we have an import cycle.
1382         // If we do, we'll lose the path that describes the cycle.
1383         if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) {
1384                 p.Error.ImportStack = stk.Copy()
1385         }
1386         return p
1387 }
1388
1389 // disallowInternal checks that srcDir (containing package importerPath, if non-empty)
1390 // is allowed to import p.
1391 // If the import is allowed, disallowInternal returns the original package p.
1392 // If not, it returns a new package containing just an appropriate error.
1393 func disallowInternal(ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
1394         // golang.org/s/go14internal:
1395         // An import of a path containing the element “internal”
1396         // is disallowed if the importing code is outside the tree
1397         // rooted at the parent of the “internal” directory.
1398
1399         // There was an error loading the package; stop here.
1400         if p.Error != nil {
1401                 return p
1402         }
1403
1404         // The generated 'testmain' package is allowed to access testing/internal/...,
1405         // as if it were generated into the testing directory tree
1406         // (it's actually in a temporary directory outside any Go tree).
1407         // This cleans up a former kludge in passing functionality to the testing package.
1408         if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {
1409                 return p
1410         }
1411
1412         // We can't check standard packages with gccgo.
1413         if cfg.BuildContext.Compiler == "gccgo" && p.Standard {
1414                 return p
1415         }
1416
1417         // The sort package depends on internal/reflectlite, but during bootstrap
1418         // the path rewriting causes the normal internal checks to fail.
1419         // Instead, just ignore the internal rules during bootstrap.
1420         if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") {
1421                 return p
1422         }
1423
1424         // importerPath is empty: we started
1425         // with a name given on the command line, not an
1426         // import. Anything listed on the command line is fine.
1427         if importerPath == "" {
1428                 return p
1429         }
1430
1431         // Check for "internal" element: three cases depending on begin of string and/or end of string.
1432         i, ok := findInternal(p.ImportPath)
1433         if !ok {
1434                 return p
1435         }
1436
1437         // Internal is present.
1438         // Map import path back to directory corresponding to parent of internal.
1439         if i > 0 {
1440                 i-- // rewind over slash in ".../internal"
1441         }
1442
1443         if p.Module == nil {
1444                 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
1445
1446                 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1447                         return p
1448                 }
1449
1450                 // Look for symlinks before reporting error.
1451                 srcDir = expandPath(srcDir)
1452                 parent = expandPath(parent)
1453                 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1454                         return p
1455                 }
1456         } else {
1457                 // p is in a module, so make it available based on the importer's import path instead
1458                 // of the file path (https://golang.org/issue/23970).
1459                 if importer.Internal.CmdlineFiles {
1460                         // The importer is a list of command-line files.
1461                         // Pretend that the import path is the import path of the
1462                         // directory containing them.
1463                         // If the directory is outside the main modules, this will resolve to ".",
1464                         // which is not a prefix of any valid module.
1465                         importerPath, _ = modload.MainModules.DirImportPath(ctx, importer.Dir)
1466                 }
1467                 parentOfInternal := p.ImportPath[:i]
1468                 if str.HasPathPrefix(importerPath, parentOfInternal) {
1469                         return p
1470                 }
1471         }
1472
1473         // Internal is present, and srcDir is outside parent's tree. Not allowed.
1474         perr := *p
1475         perr.Error = &PackageError{
1476                 alwaysPrintStack: true,
1477                 ImportStack:      stk.Copy(),
1478                 Err:              ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"),
1479         }
1480         perr.Incomplete = true
1481         return &perr
1482 }
1483
1484 // findInternal looks for the final "internal" path element in the given import path.
1485 // If there isn't one, findInternal returns ok=false.
1486 // Otherwise, findInternal returns ok=true and the index of the "internal".
1487 func findInternal(path string) (index int, ok bool) {
1488         // Three cases, depending on internal at start/end of string or not.
1489         // The order matters: we must return the index of the final element,
1490         // because the final one produces the most restrictive requirement
1491         // on the importer.
1492         switch {
1493         case strings.HasSuffix(path, "/internal"):
1494                 return len(path) - len("internal"), true
1495         case strings.Contains(path, "/internal/"):
1496                 return strings.LastIndex(path, "/internal/") + 1, true
1497         case path == "internal", strings.HasPrefix(path, "internal/"):
1498                 return 0, true
1499         }
1500         return 0, false
1501 }
1502
1503 // disallowVendor checks that srcDir is allowed to import p as path.
1504 // If the import is allowed, disallowVendor returns the original package p.
1505 // If not, it returns a new package containing just an appropriate error.
1506 func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *Package {
1507         // If the importerPath is empty, we started
1508         // with a name given on the command line, not an
1509         // import. Anything listed on the command line is fine.
1510         if importerPath == "" {
1511                 return p
1512         }
1513
1514         if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != p {
1515                 return perr
1516         }
1517
1518         // Paths like x/vendor/y must be imported as y, never as x/vendor/y.
1519         if i, ok := FindVendor(path); ok {
1520                 perr := *p
1521                 perr.Error = &PackageError{
1522                         ImportStack: stk.Copy(),
1523                         Err:         ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]),
1524                 }
1525                 perr.Incomplete = true
1526                 return &perr
1527         }
1528
1529         return p
1530 }
1531
1532 // disallowVendorVisibility checks that srcDir is allowed to import p.
1533 // The rules are the same as for /internal/ except that a path ending in /vendor
1534 // is not subject to the rules, only subdirectories of vendor.
1535 // This allows people to have packages and commands named vendor,
1536 // for maximal compatibility with existing source trees.
1537 func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *Package {
1538         // The stack does not include p.ImportPath.
1539         // If there's nothing on the stack, we started
1540         // with a name given on the command line, not an
1541         // import. Anything listed on the command line is fine.
1542         if importerPath == "" {
1543                 return p
1544         }
1545
1546         // Check for "vendor" element.
1547         i, ok := FindVendor(p.ImportPath)
1548         if !ok {
1549                 return p
1550         }
1551
1552         // Vendor is present.
1553         // Map import path back to directory corresponding to parent of vendor.
1554         if i > 0 {
1555                 i-- // rewind over slash in ".../vendor"
1556         }
1557         truncateTo := i + len(p.Dir) - len(p.ImportPath)
1558         if truncateTo < 0 || len(p.Dir) < truncateTo {
1559                 return p
1560         }
1561         parent := p.Dir[:truncateTo]
1562         if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1563                 return p
1564         }
1565
1566         // Look for symlinks before reporting error.
1567         srcDir = expandPath(srcDir)
1568         parent = expandPath(parent)
1569         if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1570                 return p
1571         }
1572
1573         // Vendor is present, and srcDir is outside parent's tree. Not allowed.
1574         perr := *p
1575         perr.Error = &PackageError{
1576                 ImportStack: stk.Copy(),
1577                 Err:         errors.New("use of vendored package not allowed"),
1578         }
1579         perr.Incomplete = true
1580         return &perr
1581 }
1582
1583 // FindVendor looks for the last non-terminating "vendor" path element in the given import path.
1584 // If there isn't one, FindVendor returns ok=false.
1585 // Otherwise, FindVendor returns ok=true and the index of the "vendor".
1586 //
1587 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
1588 // not the vendored copy of an import "" (the empty import path).
1589 // This will allow people to have packages or commands named vendor.
1590 // This may help reduce breakage, or it may just be confusing. We'll see.
1591 func FindVendor(path string) (index int, ok bool) {
1592         // Two cases, depending on internal at start of string or not.
1593         // The order matters: we must return the index of the final element,
1594         // because the final one is where the effective import path starts.
1595         switch {
1596         case strings.Contains(path, "/vendor/"):
1597                 return strings.LastIndex(path, "/vendor/") + 1, true
1598         case strings.HasPrefix(path, "vendor/"):
1599                 return 0, true
1600         }
1601         return 0, false
1602 }
1603
1604 type TargetDir int
1605
1606 const (
1607         ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
1608         ToBin                      // to bin dir inside package root (default for non-cmd/*)
1609         StalePath                  // an old import path; fail to build
1610 )
1611
1612 // InstallTargetDir reports the target directory for installing the command p.
1613 func InstallTargetDir(p *Package) TargetDir {
1614         if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
1615                 return StalePath
1616         }
1617         if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
1618                 switch p.ImportPath {
1619                 case "cmd/go", "cmd/gofmt":
1620                         return ToBin
1621                 }
1622                 return ToTool
1623         }
1624         return ToBin
1625 }
1626
1627 var cgoExclude = map[string]bool{
1628         "runtime/cgo": true,
1629 }
1630
1631 var cgoSyscallExclude = map[string]bool{
1632         "runtime/cgo":  true,
1633         "runtime/race": true,
1634         "runtime/msan": true,
1635         "runtime/asan": true,
1636 }
1637
1638 var foldPath = make(map[string]string)
1639
1640 // exeFromImportPath returns an executable name
1641 // for a package using the import path.
1642 //
1643 // The executable name is the last element of the import path.
1644 // In module-aware mode, an additional rule is used on import paths
1645 // consisting of two or more path elements. If the last element is
1646 // a vN path element specifying the major version, then the
1647 // second last element of the import path is used instead.
1648 func (p *Package) exeFromImportPath() string {
1649         _, elem := pathpkg.Split(p.ImportPath)
1650         if cfg.ModulesEnabled {
1651                 // If this is example.com/mycmd/v2, it's more useful to
1652                 // install it as mycmd than as v2. See golang.org/issue/24667.
1653                 if elem != p.ImportPath && isVersionElement(elem) {
1654                         _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
1655                 }
1656         }
1657         return elem
1658 }
1659
1660 // exeFromFiles returns an executable name for a package
1661 // using the first element in GoFiles or CgoFiles collections without the prefix.
1662 //
1663 // Returns empty string in case of empty collection.
1664 func (p *Package) exeFromFiles() string {
1665         var src string
1666         if len(p.GoFiles) > 0 {
1667                 src = p.GoFiles[0]
1668         } else if len(p.CgoFiles) > 0 {
1669                 src = p.CgoFiles[0]
1670         } else {
1671                 return ""
1672         }
1673         _, elem := filepath.Split(src)
1674         return elem[:len(elem)-len(".go")]
1675 }
1676
1677 // DefaultExecName returns the default executable name for a package
1678 func (p *Package) DefaultExecName() string {
1679         if p.Internal.CmdlineFiles {
1680                 return p.exeFromFiles()
1681         }
1682         return p.exeFromImportPath()
1683 }
1684
1685 // load populates p using information from bp, err, which should
1686 // be the result of calling build.Context.Import.
1687 // stk contains the import stack, not including path itself.
1688 func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
1689         p.copyBuild(opts, bp)
1690
1691         // The localPrefix is the path we interpret ./ imports relative to,
1692         // if we support them at all (not in module mode!).
1693         // Synthesized main packages sometimes override this.
1694         if p.Internal.Local && !cfg.ModulesEnabled {
1695                 p.Internal.LocalPrefix = dirToImportPath(p.Dir)
1696         }
1697
1698         // setError sets p.Error if it hasn't already been set. We may proceed
1699         // after encountering some errors so that 'go list -e' has more complete
1700         // output. If there's more than one error, we should report the first.
1701         setError := func(err error) {
1702                 if p.Error == nil {
1703                         p.Error = &PackageError{
1704                                 ImportStack: stk.Copy(),
1705                                 Err:         err,
1706                         }
1707
1708                         // Add the importer's position information if the import position exists, and
1709                         // the current package being examined is the importer.
1710                         // If we have not yet accepted package p onto the import stack,
1711                         // then the cause of the error is not within p itself: the error
1712                         // must be either in an explicit command-line argument,
1713                         // or on the importer side (indicated by a non-empty importPos).
1714                         if path != stk.Top() && len(importPos) > 0 {
1715                                 p.Error.setPos(importPos)
1716                         }
1717                 }
1718         }
1719
1720         if err != nil {
1721                 p.Incomplete = true
1722                 p.setLoadPackageDataError(err, path, stk, importPos)
1723         }
1724
1725         useBindir := p.Name == "main"
1726         if !p.Standard {
1727                 switch cfg.BuildBuildmode {
1728                 case "c-archive", "c-shared", "plugin":
1729                         useBindir = false
1730                 }
1731         }
1732
1733         if useBindir {
1734                 // Report an error when the old code.google.com/p/go.tools paths are used.
1735                 if InstallTargetDir(p) == StalePath {
1736                         // TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so
1737                         // old, even this code checking for it is stale now!
1738                         newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
1739                         e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath)
1740                         setError(e)
1741                         return
1742                 }
1743                 elem := p.DefaultExecName()
1744                 full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
1745                 if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
1746                         // Install cross-compiled binaries to subdirectories of bin.
1747                         elem = full
1748                 }
1749                 if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {
1750                         p.Internal.Build.BinDir = modload.BinDir()
1751                 }
1752                 if p.Internal.Build.BinDir != "" {
1753                         // Install to GOBIN or bin of GOPATH entry.
1754                         p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
1755                         if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" {
1756                                 // Do not create $GOBIN/goos_goarch/elem.
1757                                 p.Target = ""
1758                                 p.Internal.GobinSubdir = true
1759                         }
1760                 }
1761                 if InstallTargetDir(p) == ToTool {
1762                         // This is for 'go tool'.
1763                         // Override all the usual logic and force it into the tool directory.
1764                         if cfg.BuildToolchainName == "gccgo" {
1765                                 p.Target = filepath.Join(base.ToolDir, elem)
1766                         } else {
1767                                 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
1768                         }
1769                 }
1770                 if p.Target != "" && cfg.BuildContext.GOOS == "windows" {
1771                         p.Target += ".exe"
1772                 }
1773         } else if p.Internal.Local {
1774                 // Local import turned into absolute path.
1775                 // No permanent install target.
1776                 p.Target = ""
1777         } else {
1778                 p.Target = p.Internal.Build.PkgObj
1779                 if cfg.BuildLinkshared && p.Target != "" {
1780                         // TODO(bcmills): The reliance on p.Target implies that -linkshared does
1781                         // not work for any package that lacks a Target — such as a non-main
1782                         // package in module mode. We should probably fix that.
1783                         shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
1784                         shlib, err := os.ReadFile(shlibnamefile)
1785                         if err != nil && !os.IsNotExist(err) {
1786                                 base.Fatalf("reading shlibname: %v", err)
1787                         }
1788                         if err == nil {
1789                                 libname := strings.TrimSpace(string(shlib))
1790                                 if cfg.BuildContext.Compiler == "gccgo" {
1791                                         p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
1792                                 } else {
1793                                         p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
1794                                 }
1795                         }
1796                 }
1797         }
1798
1799         // Build augmented import list to add implicit dependencies.
1800         // Be careful not to add imports twice, just to avoid confusion.
1801         importPaths := p.Imports
1802         addImport := func(path string, forCompiler bool) {
1803                 for _, p := range importPaths {
1804                         if path == p {
1805                                 return
1806                         }
1807                 }
1808                 importPaths = append(importPaths, path)
1809                 if forCompiler {
1810                         p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)
1811                 }
1812         }
1813
1814         if !opts.IgnoreImports {
1815                 // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
1816                 // except for certain packages, to avoid circular dependencies.
1817                 if p.UsesCgo() {
1818                         addImport("unsafe", true)
1819                 }
1820                 if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
1821                         addImport("runtime/cgo", true)
1822                 }
1823                 if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
1824                         addImport("syscall", true)
1825                 }
1826
1827                 // SWIG adds imports of some standard packages.
1828                 if p.UsesSwig() {
1829                         addImport("unsafe", true)
1830                         if cfg.BuildContext.Compiler != "gccgo" {
1831                                 addImport("runtime/cgo", true)
1832                         }
1833                         addImport("syscall", true)
1834                         addImport("sync", true)
1835
1836                         // TODO: The .swig and .swigcxx files can use
1837                         // %go_import directives to import other packages.
1838                 }
1839
1840                 // The linker loads implicit dependencies.
1841                 if p.Name == "main" && !p.Internal.ForceLibrary {
1842                         for _, dep := range LinkerDeps(p) {
1843                                 addImport(dep, false)
1844                         }
1845                 }
1846         }
1847
1848         // Check for case-insensitive collisions of import paths.
1849         fold := str.ToFold(p.ImportPath)
1850         if other := foldPath[fold]; other == "" {
1851                 foldPath[fold] = p.ImportPath
1852         } else if other != p.ImportPath {
1853                 setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
1854                 return
1855         }
1856
1857         if !SafeArg(p.ImportPath) {
1858                 setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
1859                 return
1860         }
1861
1862         // Errors after this point are caused by this package, not the importing
1863         // package. Pushing the path here prevents us from reporting the error
1864         // with the position of the import declaration.
1865         stk.Push(path)
1866         defer stk.Pop()
1867
1868         pkgPath := p.ImportPath
1869         if p.Internal.CmdlineFiles {
1870                 pkgPath = "command-line-arguments"
1871         }
1872         if cfg.ModulesEnabled {
1873                 p.Module = modload.PackageModuleInfo(ctx, pkgPath)
1874         }
1875
1876         p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
1877         if err != nil {
1878                 p.Incomplete = true
1879                 setError(err)
1880                 embedErr := err.(*EmbedError)
1881                 p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])
1882         }
1883
1884         // Check for case-insensitive collision of input files.
1885         // To avoid problems on case-insensitive files, we reject any package
1886         // where two different input files have equal names under a case-insensitive
1887         // comparison.
1888         inputs := p.AllFiles()
1889         f1, f2 := str.FoldDup(inputs)
1890         if f1 != "" {
1891                 setError(fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2))
1892                 return
1893         }
1894
1895         // If first letter of input file is ASCII, it must be alphanumeric.
1896         // This avoids files turning into flags when invoking commands,
1897         // and other problems we haven't thought of yet.
1898         // Also, _cgo_ files must be generated by us, not supplied.
1899         // They are allowed to have //go:cgo_ldflag directives.
1900         // The directory scan ignores files beginning with _,
1901         // so we shouldn't see any _cgo_ files anyway, but just be safe.
1902         for _, file := range inputs {
1903                 if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
1904                         setError(fmt.Errorf("invalid input file name %q", file))
1905                         return
1906                 }
1907         }
1908         if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
1909                 setError(fmt.Errorf("invalid input directory name %q", name))
1910                 return
1911         }
1912
1913         // Build list of imported packages and full dependency list.
1914         imports := make([]*Package, 0, len(p.Imports))
1915         for i, path := range importPaths {
1916                 if path == "C" {
1917                         continue
1918                 }
1919                 p1 := LoadImport(ctx, opts, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
1920
1921                 path = p1.ImportPath
1922                 importPaths[i] = path
1923                 if i < len(p.Imports) {
1924                         p.Imports[i] = path
1925                 }
1926
1927                 imports = append(imports, p1)
1928                 if p1.Incomplete {
1929                         p.Incomplete = true
1930                 }
1931         }
1932         p.Internal.Imports = imports
1933         p.collectDeps()
1934         if p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
1935                 p.setBuildInfo()
1936         }
1937
1938         // unsafe is a fake package.
1939         if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
1940                 p.Target = ""
1941         }
1942
1943         // If cgo is not enabled, ignore cgo supporting sources
1944         // just as we ignore go files containing import "C".
1945         if !cfg.BuildContext.CgoEnabled {
1946                 p.CFiles = nil
1947                 p.CXXFiles = nil
1948                 p.MFiles = nil
1949                 p.SwigFiles = nil
1950                 p.SwigCXXFiles = nil
1951                 // Note that SFiles are okay (they go to the Go assembler)
1952                 // and HFiles are okay (they might be used by the SFiles).
1953                 // Also Sysofiles are okay (they might not contain object
1954                 // code; see issue #16050).
1955         }
1956
1957         // The gc toolchain only permits C source files with cgo or SWIG.
1958         if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
1959                 setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
1960                 return
1961         }
1962
1963         // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
1964         // regardless of toolchain.
1965         if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1966                 setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
1967                 return
1968         }
1969         if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1970                 setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
1971                 return
1972         }
1973         if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1974                 setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
1975                 return
1976         }
1977 }
1978
1979 // An EmbedError indicates a problem with a go:embed directive.
1980 type EmbedError struct {
1981         Pattern string
1982         Err     error
1983 }
1984
1985 func (e *EmbedError) Error() string {
1986         return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
1987 }
1988
1989 func (e *EmbedError) Unwrap() error {
1990         return e.Err
1991 }
1992
1993 // ResolveEmbed resolves //go:embed patterns and returns only the file list.
1994 // For use by go mod vendor to find embedded files it should copy into the
1995 // vendor directory.
1996 // TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just
1997 // call (*Package).ResolveEmbed
1998 func ResolveEmbed(dir string, patterns []string) ([]string, error) {
1999         files, _, err := resolveEmbed(dir, patterns)
2000         return files, err
2001 }
2002
2003 // resolveEmbed resolves //go:embed patterns to precise file lists.
2004 // It sets files to the list of unique files matched (for go list),
2005 // and it sets pmap to the more precise mapping from
2006 // patterns to files.
2007 func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) {
2008         var pattern string
2009         defer func() {
2010                 if err != nil {
2011                         err = &EmbedError{
2012                                 Pattern: pattern,
2013                                 Err:     err,
2014                         }
2015                 }
2016         }()
2017
2018         // TODO(rsc): All these messages need position information for better error reports.
2019         pmap = make(map[string][]string)
2020         have := make(map[string]int)
2021         dirOK := make(map[string]bool)
2022         pid := 0 // pattern ID, to allow reuse of have map
2023         for _, pattern = range patterns {
2024                 pid++
2025
2026                 glob := pattern
2027                 all := strings.HasPrefix(pattern, "all:")
2028                 if all {
2029                         glob = pattern[len("all:"):]
2030                 }
2031                 // Check pattern is valid for //go:embed.
2032                 if _, err := path.Match(glob, ""); err != nil || !validEmbedPattern(glob) {
2033                         return nil, nil, fmt.Errorf("invalid pattern syntax")
2034                 }
2035
2036                 // Glob to find matches.
2037                 match, err := fsys.Glob(pkgdir + string(filepath.Separator) + filepath.FromSlash(glob))
2038                 if err != nil {
2039                         return nil, nil, err
2040                 }
2041
2042                 // Filter list of matches down to the ones that will still exist when
2043                 // the directory is packaged up as a module. (If p.Dir is in the module cache,
2044                 // only those files exist already, but if p.Dir is in the current module,
2045                 // then there may be other things lying around, like symbolic links or .git directories.)
2046                 var list []string
2047                 for _, file := range match {
2048                         rel := filepath.ToSlash(file[len(pkgdir)+1:]) // file, relative to p.Dir
2049
2050                         what := "file"
2051                         info, err := fsys.Lstat(file)
2052                         if err != nil {
2053                                 return nil, nil, err
2054                         }
2055                         if info.IsDir() {
2056                                 what = "directory"
2057                         }
2058
2059                         // Check that directories along path do not begin a new module
2060                         // (do not contain a go.mod).
2061                         for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
2062                                 if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
2063                                         return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
2064                                 }
2065                                 if dir != file {
2066                                         if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
2067                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
2068                                         }
2069                                 }
2070                                 dirOK[dir] = true
2071                                 if elem := filepath.Base(dir); isBadEmbedName(elem) {
2072                                         if dir == file {
2073                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
2074                                         } else {
2075                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
2076                                         }
2077                                 }
2078                         }
2079
2080                         switch {
2081                         default:
2082                                 return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
2083
2084                         case info.Mode().IsRegular():
2085                                 if have[rel] != pid {
2086                                         have[rel] = pid
2087                                         list = append(list, rel)
2088                                 }
2089
2090                         case info.IsDir():
2091                                 // Gather all files in the named directory, stopping at module boundaries
2092                                 // and ignoring files that wouldn't be packaged into a module.
2093                                 count := 0
2094                                 err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error {
2095                                         if err != nil {
2096                                                 return err
2097                                         }
2098                                         rel := filepath.ToSlash(path[len(pkgdir)+1:])
2099                                         name := info.Name()
2100                                         if path != file && (isBadEmbedName(name) || ((name[0] == '.' || name[0] == '_') && !all)) {
2101                                                 // Ignore bad names, assuming they won't go into modules.
2102                                                 // Also avoid hidden files that user may not know about.
2103                                                 // See golang.org/issue/42328.
2104                                                 if info.IsDir() {
2105                                                         return fs.SkipDir
2106                                                 }
2107                                                 return nil
2108                                         }
2109                                         if info.IsDir() {
2110                                                 if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
2111                                                         return filepath.SkipDir
2112                                                 }
2113                                                 return nil
2114                                         }
2115                                         if !info.Mode().IsRegular() {
2116                                                 return nil
2117                                         }
2118                                         count++
2119                                         if have[rel] != pid {
2120                                                 have[rel] = pid
2121                                                 list = append(list, rel)
2122                                         }
2123                                         return nil
2124                                 })
2125                                 if err != nil {
2126                                         return nil, nil, err
2127                                 }
2128                                 if count == 0 {
2129                                         return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel)
2130                                 }
2131                         }
2132                 }
2133
2134                 if len(list) == 0 {
2135                         return nil, nil, fmt.Errorf("no matching files found")
2136                 }
2137                 sort.Strings(list)
2138                 pmap[pattern] = list
2139         }
2140
2141         for file := range have {
2142                 files = append(files, file)
2143         }
2144         sort.Strings(files)
2145         return files, pmap, nil
2146 }
2147
2148 func validEmbedPattern(pattern string) bool {
2149         return pattern != "." && fs.ValidPath(pattern)
2150 }
2151
2152 // isBadEmbedName reports whether name is the base name of a file that
2153 // can't or won't be included in modules and therefore shouldn't be treated
2154 // as existing for embedding.
2155 func isBadEmbedName(name string) bool {
2156         if err := module.CheckFilePath(name); err != nil {
2157                 return true
2158         }
2159         switch name {
2160         // Empty string should be impossible but make it bad.
2161         case "":
2162                 return true
2163         // Version control directories won't be present in module.
2164         case ".bzr", ".hg", ".git", ".svn":
2165                 return true
2166         }
2167         return false
2168 }
2169
2170 // collectDeps populates p.Deps and p.DepsErrors by iterating over
2171 // p.Internal.Imports.
2172 //
2173 // TODO(jayconrod): collectDeps iterates over transitive imports for every
2174 // package. We should only need to visit direct imports.
2175 func (p *Package) collectDeps() {
2176         deps := make(map[string]*Package)
2177         var q []*Package
2178         q = append(q, p.Internal.Imports...)
2179         for i := 0; i < len(q); i++ {
2180                 p1 := q[i]
2181                 path := p1.ImportPath
2182                 // The same import path could produce an error or not,
2183                 // depending on what tries to import it.
2184                 // Prefer to record entries with errors, so we can report them.
2185                 p0 := deps[path]
2186                 if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
2187                         deps[path] = p1
2188                         for _, p2 := range p1.Internal.Imports {
2189                                 if deps[p2.ImportPath] != p2 {
2190                                         q = append(q, p2)
2191                                 }
2192                         }
2193                 }
2194         }
2195
2196         p.Deps = make([]string, 0, len(deps))
2197         for dep := range deps {
2198                 p.Deps = append(p.Deps, dep)
2199         }
2200         sort.Strings(p.Deps)
2201         for _, dep := range p.Deps {
2202                 p1 := deps[dep]
2203                 if p1 == nil {
2204                         panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
2205                 }
2206                 if p1.Error != nil {
2207                         p.DepsErrors = append(p.DepsErrors, p1.Error)
2208                 }
2209         }
2210 }
2211
2212 // vcsStatusCache maps repository directories (string)
2213 // to their VCS information (vcsStatusError).
2214 var vcsStatusCache par.Cache
2215
2216 // setBuildInfo gathers build information, formats it as a string to be
2217 // embedded in the binary, then sets p.Internal.BuildInfo to that string.
2218 // setBuildInfo should only be called on a main package with no errors.
2219 //
2220 // This information can be retrieved using debug.ReadBuildInfo.
2221 //
2222 // Note that the GoVersion field is not set here to avoid encoding it twice.
2223 // It is stored separately in the binary, mostly for historical reasons.
2224 func (p *Package) setBuildInfo() {
2225         // TODO: build and vcs information is not embedded for executables in GOROOT.
2226         // cmd/dist uses -gcflags=all= -ldflags=all= by default, which means these
2227         // executables always appear stale unless the user sets the same flags.
2228         // Perhaps it's safe to omit those flags when GO_GCFLAGS and GO_LDFLAGS
2229         // are not set?
2230         setPkgErrorf := func(format string, args ...any) {
2231                 if p.Error == nil {
2232                         p.Error = &PackageError{Err: fmt.Errorf(format, args...)}
2233                 }
2234         }
2235
2236         var debugModFromModinfo func(*modinfo.ModulePublic) *debug.Module
2237         debugModFromModinfo = func(mi *modinfo.ModulePublic) *debug.Module {
2238                 dm := &debug.Module{
2239                         Path:    mi.Path,
2240                         Version: mi.Version,
2241                 }
2242                 if mi.Replace != nil {
2243                         dm.Replace = debugModFromModinfo(mi.Replace)
2244                 } else {
2245                         dm.Sum = modfetch.Sum(module.Version{Path: mi.Path, Version: mi.Version})
2246                 }
2247                 return dm
2248         }
2249
2250         var main debug.Module
2251         if p.Module != nil {
2252                 main = *debugModFromModinfo(p.Module)
2253         }
2254
2255         visited := make(map[*Package]bool)
2256         mdeps := make(map[module.Version]*debug.Module)
2257         var q []*Package
2258         q = append(q, p.Internal.Imports...)
2259         for len(q) > 0 {
2260                 p1 := q[0]
2261                 q = q[1:]
2262                 if visited[p1] {
2263                         continue
2264                 }
2265                 visited[p1] = true
2266                 if p1.Module != nil {
2267                         m := module.Version{Path: p1.Module.Path, Version: p1.Module.Version}
2268                         if p1.Module.Path != main.Path && mdeps[m] == nil {
2269                                 mdeps[m] = debugModFromModinfo(p1.Module)
2270                         }
2271                 }
2272                 q = append(q, p1.Internal.Imports...)
2273         }
2274         sortedMods := make([]module.Version, 0, len(mdeps))
2275         for mod := range mdeps {
2276                 sortedMods = append(sortedMods, mod)
2277         }
2278         module.Sort(sortedMods)
2279         deps := make([]*debug.Module, len(sortedMods))
2280         for i, mod := range sortedMods {
2281                 deps[i] = mdeps[mod]
2282         }
2283
2284         pkgPath := p.ImportPath
2285         if p.Internal.CmdlineFiles {
2286                 pkgPath = "command-line-arguments"
2287         }
2288         info := &debug.BuildInfo{
2289                 Path: pkgPath,
2290                 Main: main,
2291                 Deps: deps,
2292         }
2293         appendSetting := func(key, value string) {
2294                 value = strings.ReplaceAll(value, "\n", " ") // make value safe
2295                 info.Settings = append(info.Settings, debug.BuildSetting{Key: key, Value: value})
2296         }
2297
2298         // Add command-line flags relevant to the build.
2299         // This is informational, not an exhaustive list.
2300         // Please keep the list sorted.
2301         if !p.Standard {
2302                 if cfg.BuildASan {
2303                         appendSetting("-asan", "true")
2304                 }
2305                 if BuildAsmflags.present {
2306                         appendSetting("-asmflags", BuildAsmflags.String())
2307                 }
2308                 appendSetting("-compiler", cfg.BuildContext.Compiler)
2309                 if BuildGccgoflags.present && cfg.BuildContext.Compiler == "gccgo" {
2310                         appendSetting("-gccgoflags", BuildGccgoflags.String())
2311                 }
2312                 if BuildGcflags.present && cfg.BuildContext.Compiler == "gc" {
2313                         appendSetting("-gcflags", BuildGcflags.String())
2314                 }
2315                 if BuildLdflags.present {
2316                         appendSetting("-ldflags", BuildLdflags.String())
2317                 }
2318                 if cfg.BuildMSan {
2319                         appendSetting("-msan", "true")
2320                 }
2321                 if cfg.BuildRace {
2322                         appendSetting("-race", "true")
2323                 }
2324                 if tags := cfg.BuildContext.BuildTags; len(tags) > 0 {
2325                         appendSetting("-tags", strings.Join(tags, ","))
2326                 }
2327                 cgo := "0"
2328                 if cfg.BuildContext.CgoEnabled {
2329                         cgo = "1"
2330                 }
2331                 appendSetting("CGO_ENABLED", cgo)
2332                 if cfg.BuildContext.CgoEnabled {
2333                         for _, name := range []string{"CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS"} {
2334                                 appendSetting(name, cfg.Getenv(name))
2335                         }
2336                 }
2337                 appendSetting("GOARCH", cfg.BuildContext.GOARCH)
2338                 if cfg.GOEXPERIMENT != "" {
2339                         appendSetting("GOEXPERIMENT", cfg.GOEXPERIMENT)
2340                 }
2341                 appendSetting("GOOS", cfg.BuildContext.GOOS)
2342                 if key, val := cfg.GetArchEnv(); key != "" && val != "" {
2343                         appendSetting(key, val)
2344                 }
2345         }
2346
2347         // Add VCS status if all conditions are true:
2348         //
2349         // - -buildvcs is enabled.
2350         // - p is contained within a main module (there may be multiple main modules
2351         //   in a workspace, but local replacements don't count).
2352         // - Both the current directory and p's module's root directory are contained
2353         //   in the same local repository.
2354         // - We know the VCS commands needed to get the status.
2355         setVCSError := func(err error) {
2356                 setPkgErrorf("error obtaining VCS status: %v\n\tUse -buildvcs=false to disable VCS stamping.", err)
2357         }
2358
2359         var repoDir string
2360         var vcsCmd *vcs.Cmd
2361         var err error
2362         const allowNesting = true
2363         if cfg.BuildBuildvcs && p.Module != nil && p.Module.Version == "" && !p.Standard {
2364                 repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting)
2365                 if err != nil && !errors.Is(err, os.ErrNotExist) {
2366                         setVCSError(err)
2367                         return
2368                 }
2369                 if !str.HasFilePathPrefix(p.Module.Dir, repoDir) &&
2370                         !str.HasFilePathPrefix(repoDir, p.Module.Dir) {
2371                         // The module containing the main package does not overlap with the
2372                         // repository containing the working directory. Don't include VCS info.
2373                         // If the repo contains the module or vice versa, but they are not
2374                         // the same directory, it's likely an error (see below).
2375                         repoDir, vcsCmd = "", nil
2376                 }
2377         }
2378         if repoDir != "" && vcsCmd.Status != nil {
2379                 // Check that the current directory, package, and module are in the same
2380                 // repository. vcs.FromDir allows nested Git repositories, but nesting
2381                 // is not allowed for other VCS tools. The current directory may be outside
2382                 // p.Module.Dir when a workspace is used.
2383                 pkgRepoDir, _, err := vcs.FromDir(p.Dir, "", allowNesting)
2384                 if err != nil {
2385                         setVCSError(err)
2386                         return
2387                 }
2388                 if pkgRepoDir != repoDir {
2389                         setVCSError(fmt.Errorf("main package is in repository %q but current directory is in repository %q", pkgRepoDir, repoDir))
2390                         return
2391                 }
2392                 modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "", allowNesting)
2393                 if err != nil {
2394                         setVCSError(err)
2395                         return
2396                 }
2397                 if modRepoDir != repoDir {
2398                         setVCSError(fmt.Errorf("main module is in repository %q but current directory is in repository %q", modRepoDir, repoDir))
2399                         return
2400                 }
2401
2402                 type vcsStatusError struct {
2403                         Status vcs.Status
2404                         Err    error
2405                 }
2406                 cached := vcsStatusCache.Do(repoDir, func() any {
2407                         st, err := vcsCmd.Status(vcsCmd, repoDir)
2408                         return vcsStatusError{st, err}
2409                 }).(vcsStatusError)
2410                 if err := cached.Err; err != nil {
2411                         setVCSError(err)
2412                         return
2413                 }
2414                 st := cached.Status
2415
2416                 appendSetting("vcs", vcsCmd.Cmd)
2417                 if st.Revision != "" {
2418                         appendSetting("vcs.revision", st.Revision)
2419                 }
2420                 if !st.CommitTime.IsZero() {
2421                         stamp := st.CommitTime.UTC().Format(time.RFC3339Nano)
2422                         appendSetting("vcs.time", stamp)
2423                 }
2424                 appendSetting("vcs.modified", strconv.FormatBool(st.Uncommitted))
2425         }
2426
2427         text, err := info.MarshalText()
2428         if err != nil {
2429                 setPkgErrorf("error formatting build info: %v", err)
2430                 return
2431         }
2432         p.Internal.BuildInfo = string(text)
2433 }
2434
2435 // SafeArg reports whether arg is a "safe" command-line argument,
2436 // meaning that when it appears in a command-line, it probably
2437 // doesn't have some special meaning other than its own name.
2438 // Obviously args beginning with - are not safe (they look like flags).
2439 // Less obviously, args beginning with @ are not safe (they look like
2440 // GNU binutils flagfile specifiers, sometimes called "response files").
2441 // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
2442 // We accept leading . _ and / as likely in file system paths.
2443 // There is a copy of this function in cmd/compile/internal/gc/noder.go.
2444 func SafeArg(name string) bool {
2445         if name == "" {
2446                 return false
2447         }
2448         c := name[0]
2449         return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
2450 }
2451
2452 // LinkerDeps returns the list of linker-induced dependencies for main package p.
2453 func LinkerDeps(p *Package) []string {
2454         // Everything links runtime.
2455         deps := []string{"runtime"}
2456
2457         // External linking mode forces an import of runtime/cgo.
2458         if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
2459                 deps = append(deps, "runtime/cgo")
2460         }
2461         // On ARM with GOARM=5, it forces an import of math, for soft floating point.
2462         if cfg.Goarch == "arm" {
2463                 deps = append(deps, "math")
2464         }
2465         // Using the race detector forces an import of runtime/race.
2466         if cfg.BuildRace {
2467                 deps = append(deps, "runtime/race")
2468         }
2469         // Using memory sanitizer forces an import of runtime/msan.
2470         if cfg.BuildMSan {
2471                 deps = append(deps, "runtime/msan")
2472         }
2473         // Using address sanitizer forces an import of runtime/asan.
2474         if cfg.BuildASan {
2475                 deps = append(deps, "runtime/asan")
2476         }
2477
2478         return deps
2479 }
2480
2481 // externalLinkingForced reports whether external linking is being
2482 // forced even for programs that do not use cgo.
2483 func externalLinkingForced(p *Package) bool {
2484         if !cfg.BuildContext.CgoEnabled {
2485                 return false
2486         }
2487
2488         // Some targets must use external linking even inside GOROOT.
2489         switch cfg.BuildContext.GOOS {
2490         case "android":
2491                 if cfg.BuildContext.GOARCH != "arm64" {
2492                         return true
2493                 }
2494         case "ios":
2495                 return true
2496         }
2497
2498         // Currently build modes c-shared, pie (on systems that do not
2499         // support PIE with internal linking mode (currently all
2500         // systems: issue #18968)), plugin, and -linkshared force
2501         // external linking mode, as of course does
2502         // -ldflags=-linkmode=external. External linking mode forces
2503         // an import of runtime/cgo.
2504         // If there are multiple -linkmode options, the last one wins.
2505         pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH)
2506         linkmodeExternal := false
2507         if p != nil {
2508                 ldflags := BuildLdflags.For(p)
2509                 for i := len(ldflags) - 1; i >= 0; i-- {
2510                         a := ldflags[i]
2511                         if a == "-linkmode=external" ||
2512                                 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
2513                                 linkmodeExternal = true
2514                                 break
2515                         } else if a == "-linkmode=internal" ||
2516                                 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" {
2517                                 break
2518                         }
2519                 }
2520         }
2521
2522         return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal
2523 }
2524
2525 // mkAbs rewrites list, which must be paths relative to p.Dir,
2526 // into a sorted list of absolute paths. It edits list in place but for
2527 // convenience also returns list back to its caller.
2528 func (p *Package) mkAbs(list []string) []string {
2529         for i, f := range list {
2530                 list[i] = filepath.Join(p.Dir, f)
2531         }
2532         sort.Strings(list)
2533         return list
2534 }
2535
2536 // InternalGoFiles returns the list of Go files being built for the package,
2537 // using absolute paths.
2538 func (p *Package) InternalGoFiles() []string {
2539         return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles))
2540 }
2541
2542 // InternalXGoFiles returns the list of Go files being built for the XTest package,
2543 // using absolute paths.
2544 func (p *Package) InternalXGoFiles() []string {
2545         return p.mkAbs(p.XTestGoFiles)
2546 }
2547
2548 // InternalGoFiles returns the list of all Go files possibly relevant for the package,
2549 // using absolute paths. "Possibly relevant" means that files are not excluded
2550 // due to build tags, but files with names beginning with . or _ are still excluded.
2551 func (p *Package) InternalAllGoFiles() []string {
2552         return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
2553 }
2554
2555 // usesSwig reports whether the package needs to run SWIG.
2556 func (p *Package) UsesSwig() bool {
2557         return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
2558 }
2559
2560 // usesCgo reports whether the package needs to run cgo
2561 func (p *Package) UsesCgo() bool {
2562         return len(p.CgoFiles) > 0
2563 }
2564
2565 // PackageList returns the list of packages in the dag rooted at roots
2566 // as visited in a depth-first post-order traversal.
2567 func PackageList(roots []*Package) []*Package {
2568         seen := map[*Package]bool{}
2569         all := []*Package{}
2570         var walk func(*Package)
2571         walk = func(p *Package) {
2572                 if seen[p] {
2573                         return
2574                 }
2575                 seen[p] = true
2576                 for _, p1 := range p.Internal.Imports {
2577                         walk(p1)
2578                 }
2579                 all = append(all, p)
2580         }
2581         for _, root := range roots {
2582                 walk(root)
2583         }
2584         return all
2585 }
2586
2587 // TestPackageList returns the list of packages in the dag rooted at roots
2588 // as visited in a depth-first post-order traversal, including the test
2589 // imports of the roots. This ignores errors in test packages.
2590 func TestPackageList(ctx context.Context, opts PackageOpts, roots []*Package) []*Package {
2591         seen := map[*Package]bool{}
2592         all := []*Package{}
2593         var walk func(*Package)
2594         walk = func(p *Package) {
2595                 if seen[p] {
2596                         return
2597                 }
2598                 seen[p] = true
2599                 for _, p1 := range p.Internal.Imports {
2600                         walk(p1)
2601                 }
2602                 all = append(all, p)
2603         }
2604         walkTest := func(root *Package, path string) {
2605                 var stk ImportStack
2606                 p1 := LoadImport(ctx, opts, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
2607                 if p1.Error == nil {
2608                         walk(p1)
2609                 }
2610         }
2611         for _, root := range roots {
2612                 walk(root)
2613                 for _, path := range root.TestImports {
2614                         walkTest(root, path)
2615                 }
2616                 for _, path := range root.XTestImports {
2617                         walkTest(root, path)
2618                 }
2619         }
2620         return all
2621 }
2622
2623 // LoadImportWithFlags loads the package with the given import path and
2624 // sets tool flags on that package. This function is useful loading implicit
2625 // dependencies (like sync/atomic for coverage).
2626 // TODO(jayconrod): delete this function and set flags automatically
2627 // in LoadImport instead.
2628 func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
2629         p := LoadImport(context.TODO(), PackageOpts{}, path, srcDir, parent, stk, importPos, mode)
2630         setToolFlags(p)
2631         return p
2632 }
2633
2634 // PackageOpts control the behavior of PackagesAndErrors and other package
2635 // loading functions.
2636 type PackageOpts struct {
2637         // IgnoreImports controls whether we ignore explicit and implicit imports
2638         // when loading packages.  Implicit imports are added when supporting Cgo
2639         // or SWIG and when linking main packages.
2640         IgnoreImports bool
2641
2642         // ModResolveTests indicates whether calls to the module loader should also
2643         // resolve test dependencies of the requested packages.
2644         //
2645         // If ModResolveTests is true, then the module loader needs to resolve test
2646         // dependencies at the same time as packages; otherwise, the test dependencies
2647         // of those packages could be missing, and resolving those missing dependencies
2648         // could change the selected versions of modules that provide other packages.
2649         ModResolveTests bool
2650
2651         // MainOnly is true if the caller only wants to load main packages.
2652         // For a literal argument matching a non-main package, a stub may be returned
2653         // with an error. For a non-literal argument (with "..."), non-main packages
2654         // are not be matched, and their dependencies may not be loaded. A warning
2655         // may be printed for non-literal arguments that match no main packages.
2656         MainOnly bool
2657 }
2658
2659 // PackagesAndErrors returns the packages named by the command line arguments
2660 // 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
2661 // a *Package with the Error field describing the failure. If errors are found
2662 // loading imported packages, the DepsErrors field is set. The Incomplete field
2663 // may be set as well.
2664 //
2665 // To obtain a flat list of packages, use PackageList.
2666 // To report errors loading packages, use ReportPackageErrors.
2667 func PackagesAndErrors(ctx context.Context, opts PackageOpts, patterns []string) []*Package {
2668         ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
2669         defer span.Done()
2670
2671         for _, p := range patterns {
2672                 // Listing is only supported with all patterns referring to either:
2673                 // - Files that are part of the same directory.
2674                 // - Explicit package paths or patterns.
2675                 if strings.HasSuffix(p, ".go") {
2676                         // We need to test whether the path is an actual Go file and not a
2677                         // package path or pattern ending in '.go' (see golang.org/issue/34653).
2678                         if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
2679                                 return []*Package{GoFilesPackage(ctx, opts, patterns)}
2680                         }
2681                 }
2682         }
2683
2684         var matches []*search.Match
2685         if modload.Init(); cfg.ModulesEnabled {
2686                 modOpts := modload.PackageOpts{
2687                         ResolveMissingImports: true,
2688                         LoadTests:             opts.ModResolveTests,
2689                         SilencePackageErrors:  true,
2690                 }
2691                 matches, _ = modload.LoadPackages(ctx, modOpts, patterns...)
2692         } else {
2693                 noModRoots := []string{}
2694                 matches = search.ImportPaths(patterns, noModRoots)
2695         }
2696
2697         var (
2698                 pkgs    []*Package
2699                 stk     ImportStack
2700                 seenPkg = make(map[*Package]bool)
2701         )
2702
2703         pre := newPreload()
2704         defer pre.flush()
2705         pre.preloadMatches(ctx, opts, matches)
2706
2707         for _, m := range matches {
2708                 for _, pkg := range m.Pkgs {
2709                         if pkg == "" {
2710                                 panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
2711                         }
2712                         p := loadImport(ctx, opts, pre, pkg, base.Cwd(), nil, &stk, nil, 0)
2713                         p.Match = append(p.Match, m.Pattern())
2714                         p.Internal.CmdlinePkg = true
2715                         if m.IsLiteral() {
2716                                 // Note: do not set = m.IsLiteral unconditionally
2717                                 // because maybe we'll see p matching both
2718                                 // a literal and also a non-literal pattern.
2719                                 p.Internal.CmdlinePkgLiteral = true
2720                         }
2721                         if seenPkg[p] {
2722                                 continue
2723                         }
2724                         seenPkg[p] = true
2725                         pkgs = append(pkgs, p)
2726                 }
2727
2728                 if len(m.Errs) > 0 {
2729                         // In addition to any packages that were actually resolved from the
2730                         // pattern, there was some error in resolving the pattern itself.
2731                         // Report it as a synthetic package.
2732                         p := new(Package)
2733                         p.ImportPath = m.Pattern()
2734                         // Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import.
2735                         var stk ImportStack
2736                         var importPos []token.Position
2737                         p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos)
2738                         p.Incomplete = true
2739                         p.Match = append(p.Match, m.Pattern())
2740                         p.Internal.CmdlinePkg = true
2741                         if m.IsLiteral() {
2742                                 p.Internal.CmdlinePkgLiteral = true
2743                         }
2744                         pkgs = append(pkgs, p)
2745                 }
2746         }
2747
2748         if opts.MainOnly {
2749                 pkgs = mainPackagesOnly(pkgs, matches)
2750         }
2751
2752         // Now that CmdlinePkg is set correctly,
2753         // compute the effective flags for all loaded packages
2754         // (not just the ones matching the patterns but also
2755         // their dependencies).
2756         setToolFlags(pkgs...)
2757
2758         return pkgs
2759 }
2760
2761 // CheckPackageErrors prints errors encountered loading pkgs and their
2762 // dependencies, then exits with a non-zero status if any errors were found.
2763 func CheckPackageErrors(pkgs []*Package) {
2764         printed := map[*PackageError]bool{}
2765         for _, pkg := range pkgs {
2766                 if pkg.Error != nil {
2767                         base.Errorf("%v", pkg.Error)
2768                         printed[pkg.Error] = true
2769                 }
2770                 for _, err := range pkg.DepsErrors {
2771                         // Since these are errors in dependencies,
2772                         // the same error might show up multiple times,
2773                         // once in each package that depends on it.
2774                         // Only print each once.
2775                         if !printed[err] {
2776                                 printed[err] = true
2777                                 base.Errorf("%v", err)
2778                         }
2779                 }
2780         }
2781         base.ExitIfErrors()
2782
2783         // Check for duplicate loads of the same package.
2784         // That should be impossible, but if it does happen then
2785         // we end up trying to build the same package twice,
2786         // usually in parallel overwriting the same files,
2787         // which doesn't work very well.
2788         seen := map[string]bool{}
2789         reported := map[string]bool{}
2790         for _, pkg := range PackageList(pkgs) {
2791                 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
2792                         reported[pkg.ImportPath] = true
2793                         base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
2794                 }
2795                 seen[pkg.ImportPath] = true
2796         }
2797         base.ExitIfErrors()
2798 }
2799
2800 // mainPackagesOnly filters out non-main packages matched only by arguments
2801 // containing "..." and returns the remaining main packages.
2802 //
2803 // Packages with missing, invalid, or ambiguous names may be treated as
2804 // possibly-main packages.
2805 //
2806 // mainPackagesOnly sets a non-main package's Error field and returns it if it
2807 // is named by a literal argument.
2808 //
2809 // mainPackagesOnly prints warnings for non-literal arguments that only match
2810 // non-main packages.
2811 func mainPackagesOnly(pkgs []*Package, matches []*search.Match) []*Package {
2812         treatAsMain := map[string]bool{}
2813         for _, m := range matches {
2814                 if m.IsLiteral() {
2815                         for _, path := range m.Pkgs {
2816                                 treatAsMain[path] = true
2817                         }
2818                 }
2819         }
2820
2821         var mains []*Package
2822         for _, pkg := range pkgs {
2823                 if pkg.Name == "main" {
2824                         treatAsMain[pkg.ImportPath] = true
2825                         mains = append(mains, pkg)
2826                         continue
2827                 }
2828
2829                 if len(pkg.InvalidGoFiles) > 0 { // TODO(#45999): && pkg.Name == "", but currently go/build sets pkg.Name arbitrarily if it is ambiguous.
2830                         // The package has (or may have) conflicting names, and we can't easily
2831                         // tell whether one of them is "main". So assume that it could be, and
2832                         // report an error for the package.
2833                         treatAsMain[pkg.ImportPath] = true
2834                 }
2835                 if treatAsMain[pkg.ImportPath] {
2836                         if pkg.Error == nil {
2837                                 pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
2838                         }
2839                         mains = append(mains, pkg)
2840                 }
2841         }
2842
2843         for _, m := range matches {
2844                 if m.IsLiteral() || len(m.Pkgs) == 0 {
2845                         continue
2846                 }
2847                 foundMain := false
2848                 for _, path := range m.Pkgs {
2849                         if treatAsMain[path] {
2850                                 foundMain = true
2851                                 break
2852                         }
2853                 }
2854                 if !foundMain {
2855                         fmt.Fprintf(os.Stderr, "go: warning: %q matched only non-main packages\n", m.Pattern())
2856                 }
2857         }
2858
2859         return mains
2860 }
2861
2862 type mainPackageError struct {
2863         importPath string
2864 }
2865
2866 func (e *mainPackageError) Error() string {
2867         return fmt.Sprintf("package %s is not a main package", e.importPath)
2868 }
2869
2870 func (e *mainPackageError) ImportPath() string {
2871         return e.importPath
2872 }
2873
2874 func setToolFlags(pkgs ...*Package) {
2875         for _, p := range PackageList(pkgs) {
2876                 p.Internal.Asmflags = BuildAsmflags.For(p)
2877                 p.Internal.Gcflags = BuildGcflags.For(p)
2878                 p.Internal.Ldflags = BuildLdflags.For(p)
2879                 p.Internal.Gccgoflags = BuildGccgoflags.For(p)
2880         }
2881 }
2882
2883 // GoFilesPackage creates a package for building a collection of Go files
2884 // (typically named on the command line). The target is named p.a for
2885 // package p or named after the first Go file for package main.
2886 func GoFilesPackage(ctx context.Context, opts PackageOpts, gofiles []string) *Package {
2887         modload.Init()
2888
2889         for _, f := range gofiles {
2890                 if !strings.HasSuffix(f, ".go") {
2891                         pkg := new(Package)
2892                         pkg.Internal.Local = true
2893                         pkg.Internal.CmdlineFiles = true
2894                         pkg.Name = f
2895                         pkg.Error = &PackageError{
2896                                 Err: fmt.Errorf("named files must be .go files: %s", pkg.Name),
2897                         }
2898                         return pkg
2899                 }
2900         }
2901
2902         var stk ImportStack
2903         ctxt := cfg.BuildContext
2904         ctxt.UseAllFiles = true
2905
2906         // Synthesize fake "directory" that only shows the named files,
2907         // to make it look like this is a standard package or
2908         // command directory. So that local imports resolve
2909         // consistently, the files must all be in the same directory.
2910         var dirent []fs.FileInfo
2911         var dir string
2912         for _, file := range gofiles {
2913                 fi, err := fsys.Stat(file)
2914                 if err != nil {
2915                         base.Fatalf("%s", err)
2916                 }
2917                 if fi.IsDir() {
2918                         base.Fatalf("%s is a directory, should be a Go file", file)
2919                 }
2920                 dir1 := filepath.Dir(file)
2921                 if dir == "" {
2922                         dir = dir1
2923                 } else if dir != dir1 {
2924                         base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
2925                 }
2926                 dirent = append(dirent, fi)
2927         }
2928         ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil }
2929
2930         if cfg.ModulesEnabled {
2931                 modload.ImportFromFiles(ctx, gofiles)
2932         }
2933
2934         var err error
2935         if dir == "" {
2936                 dir = base.Cwd()
2937         }
2938         dir, err = filepath.Abs(dir)
2939         if err != nil {
2940                 base.Fatalf("%s", err)
2941         }
2942
2943         bp, err := ctxt.ImportDir(dir, 0)
2944         pkg := new(Package)
2945         pkg.Internal.Local = true
2946         pkg.Internal.CmdlineFiles = true
2947         pkg.load(ctx, opts, "command-line-arguments", &stk, nil, bp, err)
2948         if !cfg.ModulesEnabled {
2949                 pkg.Internal.LocalPrefix = dirToImportPath(dir)
2950         }
2951         pkg.ImportPath = "command-line-arguments"
2952         pkg.Target = ""
2953         pkg.Match = gofiles
2954
2955         if pkg.Name == "main" {
2956                 exe := pkg.DefaultExecName() + cfg.ExeSuffix
2957
2958                 if cfg.GOBIN != "" {
2959                         pkg.Target = filepath.Join(cfg.GOBIN, exe)
2960                 } else if cfg.ModulesEnabled {
2961                         pkg.Target = filepath.Join(modload.BinDir(), exe)
2962                 }
2963         }
2964
2965         if opts.MainOnly && pkg.Name != "main" && pkg.Error == nil {
2966                 pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
2967         }
2968         setToolFlags(pkg)
2969
2970         return pkg
2971 }
2972
2973 // PackagesAndErrorsOutsideModule is like PackagesAndErrors but runs in
2974 // module-aware mode and ignores the go.mod file in the current directory or any
2975 // parent directory, if there is one. This is used in the implementation of 'go
2976 // install pkg@version' and other commands that support similar forms.
2977 //
2978 // modload.ForceUseModules must be true, and modload.RootMode must be NoRoot
2979 // before calling this function.
2980 //
2981 // PackagesAndErrorsOutsideModule imposes several constraints to avoid
2982 // ambiguity. All arguments must have the same version suffix (not just a suffix
2983 // that resolves to the same version). They must refer to packages in the same
2984 // module, which must not be std or cmd. That module is not considered the main
2985 // module, but its go.mod file (if it has one) must not contain directives that
2986 // would cause it to be interpreted differently if it were the main module
2987 // (replace, exclude).
2988 func PackagesAndErrorsOutsideModule(ctx context.Context, opts PackageOpts, args []string) ([]*Package, error) {
2989         if !modload.ForceUseModules {
2990                 panic("modload.ForceUseModules must be true")
2991         }
2992         if modload.RootMode != modload.NoRoot {
2993                 panic("modload.RootMode must be NoRoot")
2994         }
2995
2996         // Check that the arguments satisfy syntactic constraints.
2997         var version string
2998         for _, arg := range args {
2999                 if i := strings.Index(arg, "@"); i >= 0 {
3000                         version = arg[i+1:]
3001                         if version == "" {
3002                                 return nil, fmt.Errorf("%s: version must not be empty", arg)
3003                         }
3004                         break
3005                 }
3006         }
3007         patterns := make([]string, len(args))
3008         for i, arg := range args {
3009                 if !strings.HasSuffix(arg, "@"+version) {
3010                         return nil, fmt.Errorf("%s: all arguments must have the same version (@%s)", arg, version)
3011                 }
3012                 p := arg[:len(arg)-len(version)-1]
3013                 switch {
3014                 case build.IsLocalImport(p):
3015                         return nil, fmt.Errorf("%s: argument must be a package path, not a relative path", arg)
3016                 case filepath.IsAbs(p):
3017                         return nil, fmt.Errorf("%s: argument must be a package path, not an absolute path", arg)
3018                 case search.IsMetaPackage(p):
3019                         return nil, fmt.Errorf("%s: argument must be a package path, not a meta-package", arg)
3020                 case path.Clean(p) != p:
3021                         return nil, fmt.Errorf("%s: argument must be a clean package path", arg)
3022                 case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
3023                         return nil, fmt.Errorf("%s: argument must not be a package in the standard library", arg)
3024                 default:
3025                         patterns[i] = p
3026                 }
3027         }
3028
3029         // Query the module providing the first argument, load its go.mod file, and
3030         // check that it doesn't contain directives that would cause it to be
3031         // interpreted differently if it were the main module.
3032         //
3033         // If multiple modules match the first argument, accept the longest match
3034         // (first result). It's possible this module won't provide packages named by
3035         // later arguments, and other modules would. Let's not try to be too
3036         // magical though.
3037         allowed := modload.CheckAllowed
3038         if modload.IsRevisionQuery(version) {
3039                 // Don't check for retractions if a specific revision is requested.
3040                 allowed = nil
3041         }
3042         noneSelected := func(path string) (version string) { return "none" }
3043         qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed)
3044         if err != nil {
3045                 return nil, fmt.Errorf("%s: %w", args[0], err)
3046         }
3047         rootMod := qrs[0].Mod
3048         data, err := modfetch.GoMod(rootMod.Path, rootMod.Version)
3049         if err != nil {
3050                 return nil, fmt.Errorf("%s: %w", args[0], err)
3051         }
3052         f, err := modfile.Parse("go.mod", data, nil)
3053         if err != nil {
3054                 return nil, fmt.Errorf("%s (in %s): %w", args[0], rootMod, err)
3055         }
3056         directiveFmt := "%s (in %s):\n" +
3057                 "\tThe go.mod file for the module providing named packages contains one or\n" +
3058                 "\tmore %s directives. It must not contain directives that would cause\n" +
3059                 "\tit to be interpreted differently than if it were the main module."
3060         if len(f.Replace) > 0 {
3061                 return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "replace")
3062         }
3063         if len(f.Exclude) > 0 {
3064                 return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "exclude")
3065         }
3066
3067         // Since we are in NoRoot mode, the build list initially contains only
3068         // the dummy command-line-arguments module. Add a requirement on the
3069         // module that provides the packages named on the command line.
3070         if _, err := modload.EditBuildList(ctx, nil, []module.Version{rootMod}); err != nil {
3071                 return nil, fmt.Errorf("%s: %w", args[0], err)
3072         }
3073
3074         // Load packages for all arguments.
3075         pkgs := PackagesAndErrors(ctx, opts, patterns)
3076
3077         // Check that named packages are all provided by the same module.
3078         for _, pkg := range pkgs {
3079                 var pkgErr error
3080                 if pkg.Module == nil {
3081                         // Packages in std, cmd, and their vendored dependencies
3082                         // don't have this field set.
3083                         pkgErr = fmt.Errorf("package %s not provided by module %s", pkg.ImportPath, rootMod)
3084                 } else if pkg.Module.Path != rootMod.Path || pkg.Module.Version != rootMod.Version {
3085                         pkgErr = fmt.Errorf("package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, rootMod)
3086                 }
3087                 if pkgErr != nil && pkg.Error == nil {
3088                         pkg.Error = &PackageError{Err: pkgErr}
3089                 }
3090         }
3091
3092         matchers := make([]func(string) bool, len(patterns))
3093         for i, p := range patterns {
3094                 if strings.Contains(p, "...") {
3095                         matchers[i] = search.MatchPattern(p)
3096                 }
3097         }
3098         return pkgs, nil
3099 }