src/cmd/go/internal/load/pkg.go GO 3,639 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,639.
1// Copyright 2011 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45// Package load loads packages.6package load78import (9	"bytes"10	"context"11	"encoding/json"12	"errors"13	"fmt"14	"go/build"15	"go/scanner"16	"go/token"17	"internal/godebug"18	"internal/platform"19	"io/fs"20	"os"21	pathpkg "path"22	"path/filepath"23	"runtime"24	"runtime/debug"25	"slices"26	"sort"27	"strconv"28	"strings"29	"time"30	"unicode"31	"unicode/utf8"3233	"cmd/internal/objabi"3435	"cmd/go/internal/base"36	"cmd/go/internal/cfg"37	"cmd/go/internal/fips140"38	"cmd/go/internal/fsys"39	"cmd/go/internal/gover"40	"cmd/go/internal/imports"41	"cmd/go/internal/modfetch"42	"cmd/go/internal/modindex"43	"cmd/go/internal/modinfo"44	"cmd/go/internal/modload"45	"cmd/go/internal/search"46	"cmd/go/internal/str"47	"cmd/go/internal/trace"48	"cmd/go/internal/vcs"49	"cmd/internal/par"50	"cmd/internal/pathcache"51	"cmd/internal/pkgpattern"5253	"golang.org/x/mod/modfile"54	"golang.org/x/mod/module"55)5657// A Package describes a single package found in a directory.58type Package struct {59	PackagePublic                 // visible in 'go list'60	Internal      PackageInternal // for use inside go command only61}6263type PackagePublic struct {64	// Note: These fields are part of the go command's public API.65	// See list.go. It is okay to add fields, but not to change or66	// remove existing ones. Keep in sync with ../list/list.go67	Dir           string                `json:",omitempty"` // directory containing package sources68	ImportPath    string                `json:",omitempty"` // import path of package in dir69	ImportComment string                `json:",omitempty"` // path in import comment on package statement70	Name          string                `json:",omitempty"` // package name71	Doc           string                `json:",omitempty"` // package documentation string72	Target        string                `json:",omitempty"` // installed target for this package (may be executable)73	Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)74	Root          string                `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package75	ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory76	ForTest       string                `json:",omitempty"` // package is only for use in named test77	Export        string                `json:",omitempty"` // file containing export data (set by go list -export)78	BuildID       string                `json:",omitempty"` // build ID of the compiled package (set by go list -export)79	Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any80	Match         []string              `json:",omitempty"` // command-line patterns matching this package81	Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?82	Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?83	DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed84	BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled85	Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?8687	DefaultGODEBUG string `json:",omitempty"` // default GODEBUG setting (only for Name=="main")8889	// Stale and StaleReason remain here *only* for the list command.90	// They are only initialized in preparation for list execution.91	// The regular build determines staleness on the fly during action execution.92	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?93	StaleReason string `json:",omitempty"` // why is Stale true?9495	// Source files96	// If you add to this list you MUST add to p.AllFiles (below) too.97	// Otherwise file name security lists will not apply to any new additions.98	GoFiles           []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)99	CgoFiles          []string `json:",omitempty"` // .go source files that import "C"100	CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles101	IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints102	InvalidGoFiles    []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)103	IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints104	CFiles            []string `json:",omitempty"` // .c source files105	CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files106	MFiles            []string `json:",omitempty"` // .m source files107	HFiles            []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files108	FFiles            []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files109	SFiles            []string `json:",omitempty"` // .s source files110	SwigFiles         []string `json:",omitempty"` // .swig files111	SwigCXXFiles      []string `json:",omitempty"` // .swigcxx files112	SysoFiles         []string `json:",omitempty"` // .syso system object files added to package113114	// Embedded files115	EmbedPatterns []string `json:",omitempty"` // //go:embed patterns116	EmbedFiles    []string `json:",omitempty"` // files matched by EmbedPatterns117118	// Cgo directives119	CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler120	CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor121	CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler122	CgoFFLAGS    []string `json:",omitempty"` // cgo: flags for Fortran compiler123	CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker124	CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names125126	// Dependency information127	Imports   []string          `json:",omitempty"` // import paths used by this package128	ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)129	Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies130131	// Error information132	// Incomplete is above, packed into the other bools133	Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)134	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies, collected by go list before output135136	// Test information137	// If you add to this list you MUST add to p.AllFiles (below) too.138	// Otherwise file name security lists will not apply to any new additions.139	TestGoFiles        []string `json:",omitempty"` // _test.go files in package140	TestImports        []string `json:",omitempty"` // imports from TestGoFiles141	TestEmbedPatterns  []string `json:",omitempty"` // //go:embed patterns142	TestEmbedFiles     []string `json:",omitempty"` // files matched by TestEmbedPatterns143	XTestGoFiles       []string `json:",omitempty"` // _test.go files outside package144	XTestImports       []string `json:",omitempty"` // imports from XTestGoFiles145	XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns146	XTestEmbedFiles    []string `json:",omitempty"` // files matched by XTestEmbedPatterns147}148149// AllFiles returns the names of all the files considered for the package.150// This is used for sanity and security checks, so we include all files,151// even IgnoredGoFiles, because some subcommands consider them.152// The go/build package filtered others out (like foo_wrongGOARCH.s)153// and that's OK.154func (p *Package) AllFiles() []string {155	files := str.StringList(156		p.GoFiles,157		p.CgoFiles,158		// no p.CompiledGoFiles, because they are from GoFiles or generated by us159		p.IgnoredGoFiles,160		// no p.InvalidGoFiles, because they are from GoFiles161		p.IgnoredOtherFiles,162		p.CFiles,163		p.CXXFiles,164		p.MFiles,165		p.HFiles,166		p.FFiles,167		p.SFiles,168		p.SwigFiles,169		p.SwigCXXFiles,170		p.SysoFiles,171		p.TestGoFiles,172		p.XTestGoFiles,173	)174175	// EmbedFiles may overlap with the other files.176	// Dedup, but delay building the map as long as possible.177	// Only files in the current directory (no slash in name)178	// need to be checked against the files variable above.179	var have map[string]bool180	for _, file := range p.EmbedFiles {181		if !strings.Contains(file, "/") {182			if have == nil {183				have = make(map[string]bool)184				for _, file := range files {185					have[file] = true186				}187			}188			if have[file] {189				continue190			}191		}192		files = append(files, file)193	}194	return files195}196197// Desc returns the package "description", for use in b.showOutput.198func (p *Package) Desc() string {199	if p.ForTest != "" {200		return p.ImportPath + " [" + p.ForTest + ".test]"201	}202	if p.Internal.ForMain != "" {203		return p.ImportPath + " [" + p.Internal.ForMain + "]"204	}205	return p.ImportPath206}207208// IsTestOnly reports whether p is a test-only package.209//210// A “test-only” package is one that:211//   - is a test-only variant of an ordinary package, or212//   - is a synthesized "main" package for a test binary, or213//   - contains only _test.go files.214func (p *Package) IsTestOnly() bool {215	return p.ForTest != "" ||216		p.Internal.TestmainGo != nil ||217		len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 && len(p.GoFiles)+len(p.CgoFiles) == 0218}219220type PackageInternal struct {221	// Unexported fields are not part of the public API.222	Build             *build.Package223	Imports           []*Package          // this package's direct imports224	CompiledImports   []string            // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports225	RawImports        []string            // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports226	ForceLibrary      bool                // this package is a library (even if named "main")227	CmdlineFiles      bool                // package built from files listed on command line228	CmdlinePkg        bool                // package listed on command line229	CmdlinePkgLiteral bool                // package listed as literal on command line (not via wildcard)230	Local             bool                // imported via local path (./ or ../)231	LocalPrefix       string              // interpret ./ and ../ imports relative to this prefix232	ExeName           string              // desired name for temporary executable233	FuzzInstrument    bool                // package should be instrumented for fuzzing234	Cover             CoverSetup          // coverage mode and other setup info of -cover is being applied to this package235	OmitDebug         bool                // tell linker not to write debug information236	GobinSubdir       bool                // install target would be subdir of GOBIN237	InternalImportOk  bool                // this package may be imported even though it is internal238	BuildInfo         *debug.BuildInfo    // add this info to package main239	TestmainGo        *[]byte             // content for _testmain.go240	Embed             map[string][]string // //go:embed comment mapping241	OrigImportPath    string              // original import path before adding '_test' suffix242	PGOProfile        string              // path to PGO profile243	ForMain           string              // the main package if this package is built specifically for it244245	Asmflags   []string // -asmflags for this package246	Gcflags    []string // -gcflags for this package247	Ldflags    []string // -ldflags for this package248	Gccgoflags []string // -gccgoflags for this package249}250251// A NoGoError indicates that no Go files for the package were applicable to the252// build for that package.253//254// That may be because there were no files whatsoever, or because all files were255// excluded, or because all non-excluded files were test sources.256type NoGoError struct {257	Package *Package258}259260func (e *NoGoError) Error() string {261	if len(e.Package.IgnoredGoFiles) > 0 {262		// Go files exist, but they were ignored due to build constraints.263		return "build constraints exclude all Go files in " + e.Package.Dir264	}265	if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {266		// Test Go files exist, but we're not interested in them.267		// The double-negative is unfortunate but we want e.Package.Dir268		// to appear at the end of error message.269		return "no non-test Go files in " + e.Package.Dir270	}271	return "no Go files in " + e.Package.Dir272}273274// setLoadPackageDataError presents an error found when loading package data275// as a *PackageError. It has special cases for some common errors to improve276// messages shown to users and reduce redundancy.277//278// setLoadPackageDataError returns true if it's safe to load information about279// imported packages, for example, if there was a parse error loading imports280// in one file, but other files are okay.281func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {282	matchErr, isMatchErr := err.(*search.MatchError)283	if isMatchErr && matchErr.Match.Pattern() == path {284		if matchErr.Match.IsLiteral() {285			// The error has a pattern has a pattern similar to the import path.286			// It may be slightly different (./foo matching example.com/foo),287			// but close enough to seem redundant.288			// Unwrap the error so we don't show the pattern.289			err = matchErr.Err290		}291	}292293	// Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.294	// The latter is more specific about the cause.295	nogoErr, ok := errors.AsType[*build.NoGoError](err)296	if ok {297		if p.Dir == "" && nogoErr.Dir != "" {298			p.Dir = nogoErr.Dir299		}300		err = &NoGoError{Package: p}301	}302303	// Take only the first error from a scanner.ErrorList. PackageError only304	// has room for one position, so we report the first error with a position305	// instead of all of the errors without a position.306	var pos string307	var isScanErr bool308	if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {309		isScanErr = true // For stack push/pop below.310311		scanPos := scanErr[0].Pos312		scanPos.Filename = base.ShortPath(scanPos.Filename)313		pos = scanPos.String()314		err = errors.New(scanErr[0].Msg)315	}316317	// Report the error on the importing package if the problem is with the import declaration318	// for example, if the package doesn't exist or if the import path is malformed.319	// On the other hand, don't include a position if the problem is with the imported package,320	// for example there are no Go files (NoGoError), or there's a problem in the imported321	// package's source files themselves (scanner errors).322	//323	// TODO(matloob): Perhaps make each of those the errors in the first group324	// (including modload.ImportMissingError, ImportMissingSumError, and the325	// corresponding "cannot find package %q in any of" GOPATH-mode error326	// produced in build.(*Context).Import; modload.AmbiguousImportError,327	// and modload.PackageNotInModuleError; and the malformed module path errors328	// produced in golang.org/x/mod/module.CheckMod) implement an interface329	// to make it easier to check for them? That would save us from having to330	// move the modload errors into this package to avoid a package import cycle,331	// and from having to export an error type for the errors produced in build.332	if !isMatchErr && (nogoErr != nil || isScanErr) {333		stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})334		defer stk.Pop()335	}336337	p.Error = &PackageError{338		ImportStack: stk.Copy(),339		Pos:         pos,340		Err:         err,341	}342	p.Incomplete = true343344	top, ok := stk.Top()345	if ok && path != top.Pkg {346		p.Error.setPos(importPos)347	}348}349350// Resolve returns the resolved version of imports,351// which should be p.TestImports or p.XTestImports, NOT p.Imports.352// The imports in p.TestImports and p.XTestImports are not recursively353// loaded during the initial load of p, so they list the imports found in354// the source file, but most processing should be over the vendor-resolved355// import paths. We do this resolution lazily both to avoid file system work356// and because the eventual real load of the test imports (during 'go test')357// can produce better error messages if it starts with the original paths.358// The initial load of p loads all the non-test imports and rewrites359// the vendored paths, so nothing should ever call p.vendored(p.Imports).360func (p *Package) Resolve(s *modload.Loader, imports []string) []string {361	if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {362		panic("internal error: p.Resolve(p.Imports) called")363	}364	seen := make(map[string]bool)365	var all []string366	for _, path := range imports {367		path = ResolveImportPath(s, p, path)368		if !seen[path] {369			seen[path] = true370			all = append(all, path)371		}372	}373	sort.Strings(all)374	return all375}376377// CoverSetup holds parameters related to coverage setup for a given package (covermode, etc).378type CoverSetup struct {379	Mode    string // coverage mode for this package380	GenMeta bool   // ask cover tool to emit a static meta data if set381}382383func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {384	p.Internal.Build = pp385386	if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {387		old := pp.PkgTargetRoot388		pp.PkgRoot = cfg.BuildPkgdir389		pp.PkgTargetRoot = cfg.BuildPkgdir390		if pp.PkgObj != "" {391			pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))392		}393	}394395	p.Dir = pp.Dir396	p.ImportPath = pp.ImportPath397	p.ImportComment = pp.ImportComment398	p.Name = pp.Name399	p.Doc = pp.Doc400	p.Root = pp.Root401	p.ConflictDir = pp.ConflictDir402	p.BinaryOnly = pp.BinaryOnly403404	// TODO? Target405	p.Goroot = pp.Goroot || fips140.Snapshot() && str.HasFilePathPrefix(p.Dir, fips140.Dir())406	p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)407	p.GoFiles = pp.GoFiles408	p.CgoFiles = pp.CgoFiles409	p.IgnoredGoFiles = pp.IgnoredGoFiles410	p.InvalidGoFiles = pp.InvalidGoFiles411	p.IgnoredOtherFiles = pp.IgnoredOtherFiles412	p.CFiles = pp.CFiles413	p.CXXFiles = pp.CXXFiles414	p.MFiles = pp.MFiles415	p.HFiles = pp.HFiles416	p.FFiles = pp.FFiles417	p.SFiles = pp.SFiles418	p.SwigFiles = pp.SwigFiles419	p.SwigCXXFiles = pp.SwigCXXFiles420	p.SysoFiles = pp.SysoFiles421	if cfg.BuildMSan {422		// There's no way for .syso files to be built both with and without423		// support for memory sanitizer. Assume they are built without,424		// and drop them.425		p.SysoFiles = nil426	}427	p.CgoCFLAGS = pp.CgoCFLAGS428	p.CgoCPPFLAGS = pp.CgoCPPFLAGS429	p.CgoCXXFLAGS = pp.CgoCXXFLAGS430	p.CgoFFLAGS = pp.CgoFFLAGS431	p.CgoLDFLAGS = pp.CgoLDFLAGS432	p.CgoPkgConfig = pp.CgoPkgConfig433	// We modify p.Imports in place, so make copy now.434	p.Imports = make([]string, len(pp.Imports))435	copy(p.Imports, pp.Imports)436	p.Internal.RawImports = pp.Imports437	p.TestGoFiles = pp.TestGoFiles438	p.TestImports = pp.TestImports439	p.XTestGoFiles = pp.XTestGoFiles440	p.XTestImports = pp.XTestImports441	if opts.IgnoreImports {442		p.Imports = nil443		p.Internal.RawImports = nil444		p.TestImports = nil445		p.XTestImports = nil446	}447	p.EmbedPatterns = pp.EmbedPatterns448	p.TestEmbedPatterns = pp.TestEmbedPatterns449	p.XTestEmbedPatterns = pp.XTestEmbedPatterns450	p.Internal.OrigImportPath = pp.ImportPath451}452453// A PackageError describes an error loading information about a package.454type PackageError struct {455	ImportStack      ImportStack // shortest path from package named on command line to this one with position456	Pos              string      // position of error457	Err              error       // the error itself458	IsImportCycle    bool        // the error is an import cycle459	alwaysPrintStack bool        // whether to always print the ImportStack460}461462func (p *PackageError) Error() string {463	// TODO(#43696): decide when to print the stack or the position based on464	// the error type and whether the package is in the main module.465	// Document the rationale.466	if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {467		// Omit import stack. The full path to the file where the error468		// is the most important thing.469		return p.Pos + ": " + p.Err.Error()470	}471472	// If the error is an ImportPathError, and the last path on the stack appears473	// in the error message, omit that path from the stack to avoid repetition.474	// If an ImportPathError wraps another ImportPathError that matches the475	// last path on the stack, we don't omit the path. An error like476	// "package A imports B: error loading C caused by B" would not be clearer477	// if "imports B" were omitted.478	if len(p.ImportStack) == 0 {479		return p.Err.Error()480	}481	var optpos string482	if p.Pos != "" {483		optpos = "\n\t" + p.Pos484	}485	imports := p.ImportStack.Pkgs()486	if p.IsImportCycle {487		imports = p.ImportStack.PkgsWithPos()488	}489	return "package " + strings.Join(imports, "\n\timports ") + optpos + ": " + p.Err.Error()490}491492func (p *PackageError) Unwrap() error { return p.Err }493494// PackageError implements MarshalJSON so that Err is marshaled as a string495// and non-essential fields are omitted.496func (p *PackageError) MarshalJSON() ([]byte, error) {497	perr := struct {498		ImportStack []string // use []string for package names499		Pos         string500		Err         string501	}{p.ImportStack.Pkgs(), p.Pos, p.Err.Error()}502	return json.Marshal(perr)503}504505func (p *PackageError) setPos(posList []token.Position) {506	if len(posList) == 0 {507		return508	}509	pos := posList[0]510	pos.Filename = base.ShortPath(pos.Filename)511	p.Pos = pos.String()512}513514// ImportPathError is a type of error that prevents a package from being loaded515// for a given import path. When such a package is loaded, a *Package is516// returned with Err wrapping an ImportPathError: the error is attached to517// the imported package, not the importing package.518//519// The string returned by ImportPath must appear in the string returned by520// Error. Errors that wrap ImportPathError (such as PackageError) may omit521// the import path.522type ImportPathError interface {523	error524	ImportPath() string525}526527var (528	_ ImportPathError = (*importError)(nil)529	_ ImportPathError = (*mainPackageError)(nil)530	_ ImportPathError = (*modload.ImportMissingError)(nil)531	_ ImportPathError = (*modload.ImportMissingSumError)(nil)532	_ ImportPathError = (*modload.DirectImportFromImplicitDependencyError)(nil)533)534535type importError struct {536	importPath string537	err        error // created with fmt.Errorf538}539540func ImportErrorf(path, format string, args ...any) ImportPathError {541	err := &importError{importPath: path, err: fmt.Errorf(format, args...)}542	if errStr := err.Error(); !strings.Contains(errStr, path) && !strings.Contains(errStr, strconv.Quote(path)) {543		panic(fmt.Sprintf("path %q not in error %q", path, errStr))544	}545	return err546}547548func (e *importError) Error() string {549	return e.err.Error()550}551552func (e *importError) Unwrap() error {553	// Don't return e.err directly, since we're only wrapping an error if %w554	// was passed to ImportErrorf.555	return errors.Unwrap(e.err)556}557558func (e *importError) ImportPath() string {559	return e.importPath560}561562type ImportInfo struct {563	Pkg string564	Pos *token.Position565}566567// An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.568// The import path of a test package is the import path of the corresponding569// non-test package with the suffix "_test" added.570type ImportStack []ImportInfo571572func NewImportInfo(pkg string, pos *token.Position) ImportInfo {573	return ImportInfo{Pkg: pkg, Pos: pos}574}575576func (s *ImportStack) Push(p ImportInfo) {577	*s = append(*s, p)578}579580func (s *ImportStack) Pop() {581	*s = (*s)[0 : len(*s)-1]582}583584func (s *ImportStack) Copy() ImportStack {585	return slices.Clone(*s)586}587588func (s *ImportStack) Pkgs() []string {589	ss := make([]string, 0, len(*s))590	for _, v := range *s {591		ss = append(ss, v.Pkg)592	}593	return ss594}595596func (s *ImportStack) PkgsWithPos() []string {597	ss := make([]string, 0, len(*s))598	for _, v := range *s {599		if v.Pos != nil {600			ss = append(ss, v.Pkg+" from "+filepath.Base(v.Pos.Filename))601		} else {602			ss = append(ss, v.Pkg)603		}604	}605	return ss606}607608func (s *ImportStack) Top() (ImportInfo, bool) {609	if len(*s) == 0 {610		return ImportInfo{}, false611	}612	return (*s)[len(*s)-1], true613}614615// shorterThan reports whether sp is shorter than t.616// We use this to record the shortest import sequence617// that leads to a particular package.618func (sp *ImportStack) shorterThan(t []string) bool {619	s := *sp620	if len(s) != len(t) {621		return len(s) < len(t)622	}623	// If they are the same length, settle ties using string ordering.624	for i := range s {625		siPkg := s[i].Pkg626		if siPkg != t[i] {627			return siPkg < t[i]628		}629	}630	return false // they are equal631}632633// dirToImportPath returns the pseudo-import path we use for a package634// outside the Go path. It begins with _/ and then contains the full path635// to the directory. If the package lives in c:\home\gopher\my\pkg then636// the pseudo-import path is _/c_/home/gopher/my/pkg.637// Using a pseudo-import path like this makes the ./ imports no longer638// a special case, so that all the code to deal with ordinary imports works639// automatically.640func dirToImportPath(dir string) string {641	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))642}643644func makeImportValid(r rune) rune {645	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.646	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"647	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {648		return '_'649	}650	return r651}652653// Mode flags for loadImport and download (in get.go).654const (655	// ResolveImport means that loadImport should do import path expansion.656	// That is, ResolveImport means that the import path came from657	// a source file and has not been expanded yet to account for658	// vendoring or possible module adjustment.659	// Every import path should be loaded initially with ResolveImport,660	// and then the expanded version (for example with the /vendor/ in it)661	// gets recorded as the canonical import path. At that point, future loads662	// of that package must not pass ResolveImport, because663	// disallowVendor will reject direct use of paths containing /vendor/.664	ResolveImport = 1 << iota665666	// ResolveModule is for download (part of "go get") and indicates667	// that the module adjustment should be done, but not vendor adjustment.668	ResolveModule669670	// GetTestDeps is for download (part of "go get") and indicates671	// that test dependencies should be fetched too.672	GetTestDeps673674	// The remainder are internal modes for calls to loadImport.675676	// cmdlinePkg is for a package mentioned on the command line.677	cmdlinePkg678679	// cmdlinePkgLiteral is for a package mentioned on the command line680	// without using any wildcards or meta-patterns.681	cmdlinePkgLiteral682683	// allow simd/internal/bridge684	allowSimdInternalBridge685)686687// LoadPackage does Load import, but without a parent package load context688func LoadPackage(ld *modload.Loader, ctx context.Context, opts PackageOpts, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {689	p, err := loadImport(ld, ctx, opts, nil, path, srcDir, nil, stk, importPos, mode)690	if err != nil {691		base.Fatalf("internal error: loadImport of %q with nil parent returned an error", path)692	}693	return p694}695696// loadImport scans the directory named by path, which must be an import path,697// but possibly a local import path (an absolute file system path or one beginning698// with ./ or ../). A local relative path is interpreted relative to srcDir.699// It returns a *Package describing the package found in that directory.700// loadImport does not set tool flags and should only be used by701// this package, as part of a bigger load operation.702// The returned PackageError, if any, describes why parent is not allowed703// to import the named package, with the error referring to importPos.704// The PackageError can only be non-nil when parent is not nil.705func loadImport(ld *modload.Loader, ctx context.Context, opts PackageOpts, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {706	ctx, span := trace.StartSpan(ctx, "modload.loadImport "+path)707	defer span.Done()708709	if path == "" {710		panic("LoadImport called with empty package path")711	}712713	var parentPath, parentRoot string714	parentIsStd := false715	if parent != nil {716		parentPath = parent.ImportPath717		parentRoot = parent.Root718		parentIsStd = parent.Standard719	}720	bp, loaded, err := loadPackageData(ld, ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)721	if loaded && pre != nil && !opts.IgnoreImports {722		pre.preloadImports(ld, ctx, opts, bp.Imports, bp)723	}724	if bp == nil {725		p := &Package{726			PackagePublic: PackagePublic{727				ImportPath: path,728				Incomplete: true,729			},730		}731		if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {732			// Only add path to the error's import stack if it's not already present733			// in the error.734			//735			// TODO(bcmills): setLoadPackageDataError itself has a similar Push / Pop736			// sequence that empirically doesn't trigger for these errors, guarded by737			// a somewhat complex condition. Figure out how to generalize that738			// condition and eliminate the explicit calls here.739			stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})740			defer stk.Pop()741		}742		p.setLoadPackageDataError(err, path, stk, nil)743		setToolFlags(ld, p)744		return p, nil745	}746747	setCmdline := func(p *Package) {748		if mode&cmdlinePkg != 0 {749			p.Internal.CmdlinePkg = true750		}751		if mode&cmdlinePkgLiteral != 0 {752			p.Internal.CmdlinePkgLiteral = true753		}754	}755756	importPath := bp.ImportPath757	var p *Package758	if cp := ld.PackageCache()[importPath]; cp != nil {759		p = cp.(*Package)760		stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})761		p = reusePackage(p, stk)762		stk.Pop()763		setCmdline(p)764	} else {765		p = new(Package)766		p.Internal.Local = build.IsLocalImport(path)767		p.ImportPath = importPath768		ld.PackageCache()[importPath] = p769770		setCmdline(p)771		setToolFlags(ld, p)772773		// Load package.774		// loadPackageData may return bp != nil even if an error occurs,775		// in order to return partial information.776		p.load(ld, ctx, opts, path, stk, importPos, bp, err)777778		if !cfg.ModulesEnabled && path != cleanImport(path) {779			p.Error = &PackageError{780				ImportStack: stk.Copy(),781				Err:         ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),782			}783			p.Incomplete = true784			p.Error.setPos(importPos)785		}786	}787788	if mode&allowSimdInternalBridge == 0 || path != SimdBridgePkg { // Special case for just this import.789		// Checked on every import because the rules depend on the code doing the importing.790		if perr := disallowInternal(ld, ctx, srcDir, parent, parentPath, p, stk); perr != nil {791			perr.setPos(importPos)792			return p, perr793		}794	}795	if mode&ResolveImport != 0 {796		if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != nil {797			perr.setPos(importPos)798			return p, perr799		}800	}801802	if p.Name == "main" && parent != nil && parent.Dir != p.Dir {803		perr := &PackageError{804			ImportStack: stk.Copy(),805			Err:         ImportErrorf(path, "import %q is a program, not an importable package", path),806		}807		perr.setPos(importPos)808		return p, perr809	}810811	if p.Internal.Local && parent != nil && !parent.Internal.Local {812		var err error813		if path == "." {814			err = ImportErrorf(path, "%s: cannot import current directory", path)815		} else {816			err = ImportErrorf(path, "local import %q in non-local package", path)817		}818		perr := &PackageError{819			ImportStack: stk.Copy(),820			Err:         err,821		}822		perr.setPos(importPos)823		return p, perr824	}825826	return p, nil827}828829func extractFirstImport(importPos []token.Position) *token.Position {830	if len(importPos) == 0 {831		return nil832	}833	return &importPos[0]834}835836// loadPackageData loads information needed to construct a *Package. The result837// is cached, and later calls to loadPackageData for the same package will return838// the same data.839//840// loadPackageData returns a non-nil package even if err is non-nil unless841// the package path is malformed (for example, the path contains "mod/" or "@").842//843// loadPackageData returns a boolean, loaded, which is true if this is the844// first time the package was loaded. Callers may preload imports in this case.845func loadPackageData(ld *modload.Loader, ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {846	ctx, span := trace.StartSpan(ctx, "load.loadPackageData "+path)847	defer span.Done()848849	if path == "" {850		panic("loadPackageData called with empty package path")851	}852853	if strings.HasPrefix(path, "mod/") {854		// Paths beginning with "mod/" might accidentally855		// look in the module cache directory tree in $GOPATH/pkg/mod/.856		// This prefix is owned by the Go core for possible use in the857		// standard library (since it does not begin with a domain name),858		// so it's OK to disallow entirely.859		return nil, false, fmt.Errorf("disallowed import path %q", path)860	}861862	if strings.Contains(path, "@") {863		return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")864	}865866	// Determine canonical package path and directory.867	// For a local import the identifier is the pseudo-import path868	// we create from the full directory to the package.869	// Otherwise it is the usual import path.870	// For vendored imports, it is the expanded form.871	//872	// Note that when modules are enabled, local import paths are normally873	// canonicalized by modload.LoadPackages before now. However, if there's an874	// error resolving a local path, it will be returned untransformed875	// so that 'go list -e' reports something useful.876	importKey := importSpec{877		path:        path,878		parentPath:  parentPath,879		parentDir:   parentDir,880		parentRoot:  parentRoot,881		parentIsStd: parentIsStd,882		mode:        mode,883	}884	r := resolvedImportCache.Do(importKey, func() resolvedImport {885		var r resolvedImport886		if newPath, dir, ok := fips140.ResolveImport(path); ok {887			r.path = newPath888			r.dir = dir889		} else if cfg.ModulesEnabled {890			r.dir, r.path, r.err = modload.Lookup(ld, parentPath, parentIsStd, path)891		} else if build.IsLocalImport(path) {892			r.dir = filepath.Join(parentDir, path)893			r.path = dirToImportPath(r.dir)894		} else if mode&ResolveImport != 0 {895			// We do our own path resolution, because we want to896			// find out the key to use in packageCache without the897			// overhead of repeated calls to buildContext.Import.898			// The code is also needed in a few other places anyway.899			r.path = resolveImportPath(ld, path, parentPath, parentDir, parentRoot, parentIsStd)900		} else if mode&ResolveModule != 0 {901			r.path = moduleImportPath(path, parentPath, parentDir, parentRoot)902		}903		if r.path == "" {904			r.path = path905		}906		return r907	})908	// Invariant: r.path is set to the resolved import path. If the path cannot909	// be resolved, r.path is set to path, the source import path.910	// r.path is never empty.911912	// Load the package from its directory. If we already found the package's913	// directory when resolving its import path, use that.914	p, err := packageDataCache.Do(r.path, func() (*build.Package, error) {915		loaded = true916		var data struct {917			p   *build.Package918			err error919		}920		if r.dir != "" {921			var buildMode build.ImportMode922			buildContext := cfg.BuildContext923			if !cfg.ModulesEnabled {924				buildMode = build.ImportComment925			} else {926				buildContext.GOPATH = "" // Clear GOPATH so packages are imported as pure module packages927			}928			modroot := modload.PackageModRoot(ld, ctx, r.path)929			if modroot == "" && str.HasFilePathPrefix(r.dir, cfg.GOROOTsrc) {930				modroot = cfg.GOROOTsrc931				gorootSrcCmd := filepath.Join(cfg.GOROOTsrc, "cmd")932				if str.HasFilePathPrefix(r.dir, gorootSrcCmd) {933					modroot = gorootSrcCmd934				}935			}936			if modroot != "" {937				if rp, err := modindex.GetPackage(modroot, r.dir); err == nil {938					data.p, data.err = rp.Import(cfg.BuildContext, buildMode)939					goto Happy940				} else if !errors.Is(err, modindex.ErrNotIndexed) {941					base.Fatal(err)942				}943			}944			data.p, data.err = buildContext.ImportDir(r.dir, buildMode)945		Happy:946			if cfg.ModulesEnabled {947				// Override data.p.Root, since ImportDir sets it to $GOPATH, if948				// the module is inside $GOPATH/src.949				if info := modload.PackageModuleInfo(ld, ctx, path); info != nil {950					data.p.Root = info.Dir951				}952			}953			if r.err != nil {954				if data.err != nil {955					// ImportDir gave us one error, and the module loader gave us another.956					// We arbitrarily choose to keep the error from ImportDir because957					// that's what our tests already expect, and it seems to provide a bit958					// more detail in most cases.959				} else if errors.Is(r.err, imports.ErrNoGo) {960					// ImportDir said there were files in the package, but the module961					// loader said there weren't. Which one is right?962					// Without this special-case hack, the TestScript/test_vet case fails963					// on the vetfail/p1 package (added in CL 83955).964					// Apparently, imports.ShouldBuild biases toward rejecting files965					// with invalid build constraints, whereas ImportDir biases toward966					// accepting them.967					//968					// TODO(#41410: Figure out how this actually ought to work and fix969					// this mess).970				} else {971					data.err = r.err972				}973			}974		} else if r.err != nil {975			data.p = new(build.Package)976			data.err = r.err977		} else if cfg.ModulesEnabled && path != "unsafe" {978			data.p = new(build.Package)979			data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)980		} else {981			buildMode := build.ImportComment982			if mode&ResolveImport == 0 || r.path != path {983				// Not vendoring, or we already found the vendored path.984				buildMode |= build.IgnoreVendor985			}986			data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode)987		}988		data.p.ImportPath = r.path989990		// Set data.p.BinDir in cases where go/build.Context.Import991		// may give us a path we don't want.992		if !data.p.Goroot {993			if cfg.GOBIN != "" {994				data.p.BinDir = cfg.GOBIN995			} else if cfg.ModulesEnabled {996				data.p.BinDir = modload.BinDir(ld)997			}998		}9991000		if !cfg.ModulesEnabled && data.err == nil &&1001			data.p.ImportComment != "" && data.p.ImportComment != path &&1002			!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {1003			data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment)1004		}1005		return data.p, data.err1006	})10071008	return p, loaded, err1009}10101011// importSpec describes an import declaration in source code. It is used as a1012// cache key for resolvedImportCache.1013type importSpec struct {1014	path                              string1015	parentPath, parentDir, parentRoot string1016	parentIsStd                       bool1017	mode                              int1018}10191020// resolvedImport holds a canonical identifier for a package. It may also contain1021// a path to the package's directory and an error if one occurred. resolvedImport1022// is the value type in resolvedImportCache.1023type resolvedImport struct {1024	path, dir string1025	err       error1026}10271028// resolvedImportCache maps import strings to canonical package names.1029var resolvedImportCache par.Cache[importSpec, resolvedImport]10301031// packageDataCache maps canonical package names (string) to package metadata.1032var packageDataCache par.ErrCache[string, *build.Package]10331034// preloadWorkerCount is the number of concurrent goroutines that can load1035// packages. Experimentally, there are diminishing returns with more than1036// 4 workers. This was measured on the following machines.1037//1038// * MacBookPro with a 4-core Intel Core i7 CPU1039// * Linux workstation with 6-core Intel Xeon CPU1040// * Linux workstation with 24-core Intel Xeon CPU1041//1042// It is very likely (though not confirmed) that this workload is limited1043// by memory bandwidth. We don't have a good way to determine the number of1044// workers that would saturate the bus though, so runtime.GOMAXPROCS1045// seems like a reasonable default.1046var preloadWorkerCount = runtime.GOMAXPROCS(0)10471048// preload holds state for managing concurrent preloading of package data.1049//1050// A preload should be created with newPreload before loading a large1051// package graph. flush must be called when package loading is complete1052// to ensure preload goroutines are no longer active. This is necessary1053// because of global mutable state that cannot safely be read and written1054// concurrently. In particular, packageDataCache may be cleared by "go get"1055// in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be1056// modified by modload.LoadPackages.1057type preload struct {1058	cancel chan struct{}1059	sema   chan struct{}1060}10611062// newPreload creates a new preloader. flush must be called later to avoid1063// accessing global state while it is being modified.1064func newPreload() *preload {1065	pre := &preload{1066		cancel: make(chan struct{}),1067		sema:   make(chan struct{}, preloadWorkerCount),1068	}1069	return pre1070}10711072// preloadMatches loads data for package paths matched by patterns.1073// When preloadMatches returns, some packages may not be loaded yet, but1074// loadPackageData and loadImport are always safe to call.1075func (pre *preload) preloadMatches(ld *modload.Loader, ctx context.Context, opts PackageOpts, matches []*search.Match) {1076	for _, m := range matches {1077		for _, pkg := range m.Pkgs {1078			select {1079			case <-pre.cancel:1080				return1081			case pre.sema <- struct{}{}:1082				go func(pkg string) {1083					mode := 0 // don't use vendoring or module import resolution1084					bp, loaded, err := loadPackageData(ld, ctx, pkg, "", base.Cwd(), "", false, mode)1085					<-pre.sema1086					if bp != nil && loaded && err == nil && !opts.IgnoreImports {1087						pre.preloadImports(ld, ctx, opts, bp.Imports, bp)1088					}1089				}(pkg)1090			}1091		}1092	}1093}10941095// preloadImports queues a list of imports for preloading.1096// When preloadImports returns, some packages may not be loaded yet,1097// but loadPackageData and loadImport are always safe to call.1098func (pre *preload) preloadImports(ld *modload.Loader, ctx context.Context, opts PackageOpts, imports []string, parent *build.Package) {1099	parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)1100	for _, path := range imports {1101		if path == "C" || path == "unsafe" {1102			continue1103		}1104		select {1105		case <-pre.cancel:1106			return1107		case pre.sema <- struct{}{}:1108			go func(path string) {1109				bp, loaded, err := loadPackageData(ld, ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)1110				<-pre.sema1111				if bp != nil && loaded && err == nil && !opts.IgnoreImports {1112					pre.preloadImports(ld, ctx, opts, bp.Imports, bp)1113				}1114			}(path)1115		}1116	}1117}11181119// flush stops pending preload operations. flush blocks until preload calls to1120// loadPackageData have completed. The preloader will not make any new calls1121// to loadPackageData.1122func (pre *preload) flush() {1123	// flush is usually deferred.1124	// Don't hang program waiting for workers on panic.1125	if v := recover(); v != nil {1126		panic(v)1127	}11281129	close(pre.cancel)1130	for i := 0; i < preloadWorkerCount; i++ {1131		pre.sema <- struct{}{}1132	}1133}11341135func cleanImport(path string) string {1136	orig := path1137	path = pathpkg.Clean(path)1138	if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {1139		path = "./" + path1140	}1141	return path1142}11431144var isDirCache par.Cache[string, bool]11451146func isDir(path string) bool {1147	return isDirCache.Do(path, func() bool {1148		fi, err := fsys.Stat(path)1149		return err == nil && fi.IsDir()1150	})1151}11521153// ResolveImportPath returns the true meaning of path when it appears in parent.1154// There are two different resolutions applied.1155// First, there is Go 1.5 vendoring (golang.org/s/go15vendor).1156// If vendor expansion doesn't trigger, then the path is also subject to1157// Go 1.11 module legacy conversion (golang.org/issue/25069).1158func ResolveImportPath(s *modload.Loader, parent *Package, path string) (found string) {1159	var parentPath, parentDir, parentRoot string1160	parentIsStd := false1161	if parent != nil {1162		parentPath = parent.ImportPath1163		parentDir = parent.Dir1164		parentRoot = parent.Root1165		parentIsStd = parent.Standard1166	}1167	return resolveImportPath(s, path, parentPath, parentDir, parentRoot, parentIsStd)1168}11691170func resolveImportPath(s *modload.Loader, path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {1171	if cfg.ModulesEnabled {1172		if _, p, e := modload.Lookup(s, parentPath, parentIsStd, path); e == nil {1173			return p1174		}1175		return path1176	}1177	found = vendoredImportPath(path, parentPath, parentDir, parentRoot)1178	if found != path {1179		return found1180	}1181	return moduleImportPath(path, parentPath, parentDir, parentRoot)1182}11831184// dirAndRoot returns the source directory and workspace root1185// for the package p, guaranteeing that root is a path prefix of dir.1186func dirAndRoot(path string, dir, root string) (string, string) {1187	origDir, origRoot := dir, root1188	dir = filepath.Clean(dir)1189	root = filepath.Join(root, "src")1190	if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir {1191		// Look for symlinks before reporting error.1192		dir = expandPath(dir)1193		root = expandPath(root)1194	}11951196	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 {1197		debug.PrintStack()1198		base.Fatalf("unexpected directory layout:\n"+1199			"	import path: %s\n"+1200			"	root: %s\n"+1201			"	dir: %s\n"+1202			"	expand root: %s\n"+1203			"	expand dir: %s\n"+1204			"	separator: %s",1205			path,1206			filepath.Join(origRoot, "src"),1207			filepath.Clean(origDir),1208			origRoot,1209			origDir,1210			string(filepath.Separator))1211	}12121213	return dir, root1214}12151216// vendoredImportPath returns the vendor-expansion of path when it appears in parent.1217// If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,1218// x/vendor/path, vendor/path, or else stay path if none of those exist.1219// vendoredImportPath returns the expanded path or, if no expansion is found, the original.1220func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) {1221	if parentRoot == "" {1222		return path1223	}12241225	dir, root := dirAndRoot(parentPath, parentDir, parentRoot)12261227	vpath := "vendor/" + path1228	for i := len(dir); i >= len(root); i-- {1229		if i < len(dir) && dir[i] != filepath.Separator {1230			continue1231		}1232		// Note: checking for the vendor directory before checking1233		// for the vendor/path directory helps us hit the1234		// isDir cache more often. It also helps us prepare a more useful1235		// list of places we looked, to report when an import is not found.1236		if !isDir(filepath.Join(dir[:i], "vendor")) {1237			continue1238		}1239		targ := filepath.Join(dir[:i], vpath)1240		if isDir(targ) && hasGoFiles(targ) {1241			importPath := parentPath1242			if importPath == "command-line-arguments" {1243				// If parent.ImportPath is 'command-line-arguments'.1244				// set to relative directory to root (also chopped root directory)1245				importPath = dir[len(root)+1:]1246			}1247			// We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.1248			// We know the import path for parent's dir.1249			// We chopped off some number of path elements and1250			// added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.1251			// Now we want to know the import path for that directory.1252			// Construct it by chopping the same number of path elements1253			// (actually the same number of bytes) from parent's import path1254			// and then append /vendor/path.1255			chopped := len(dir) - i1256			if chopped == len(importPath)+1 {1257				// We walked up from c:\gopath\src\foo\bar1258				// and found c:\gopath\src\vendor\path.1259				// We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).1260				// Use "vendor/path" without any prefix.1261				return vpath1262			}1263			return importPath[:len(importPath)-chopped] + "/" + vpath1264		}1265	}1266	return path1267}12681269var (1270	modulePrefix   = []byte("\nmodule ")1271	goModPathCache par.Cache[string, string]1272)12731274// goModPath returns the module path in the go.mod in dir, if any.1275func goModPath(dir string) (path string) {1276	return goModPathCache.Do(dir, func() string {1277		data, err := os.ReadFile(filepath.Join(dir, "go.mod"))1278		if err != nil {1279			return ""1280		}1281		var i int1282		if bytes.HasPrefix(data, modulePrefix[1:]) {1283			i = 01284		} else {1285			i = bytes.Index(data, modulePrefix)1286			if i < 0 {1287				return ""1288			}1289			i++1290		}1291		line := data[i:]12921293		// Cut line at \n, drop trailing \r if present.1294		if j := bytes.IndexByte(line, '\n'); j >= 0 {1295			line = line[:j]1296		}1297		if line[len(line)-1] == '\r' {1298			line = line[:len(line)-1]1299		}1300		line = line[len("module "):]13011302		// If quoted, unquote.1303		path = strings.TrimSpace(string(line))1304		if path != "" && path[0] == '"' {1305			s, err := strconv.Unquote(path)1306			if err != nil {1307				return ""1308			}1309			path = s1310		}1311		return path1312	})1313}13141315// findVersionElement returns the slice indices of the final version element /vN in path.1316// If there is no such element, it returns -1, -1.1317func findVersionElement(path string) (i, j int) {1318	j = len(path)1319	for i = len(path) - 1; i >= 0; i-- {1320		if path[i] == '/' {1321			if isVersionElement(path[i+1 : j]) {1322				return i, j1323			}1324			j = i1325		}1326	}1327	return -1, -11328}13291330// isVersionElement reports whether s is a well-formed path version element:1331// v2, v3, v10, etc, but not v0, v05, v1.1332func isVersionElement(s string) bool {1333	if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 {1334		return false1335	}1336	for i := 1; i < len(s); i++ {1337		if s[i] < '0' || '9' < s[i] {1338			return false1339		}1340	}1341	return true1342}13431344// moduleImportPath translates import paths found in go modules1345// back down to paths that can be resolved in ordinary builds.1346//1347// Define “new” code as code with a go.mod file in the same directory1348// or a parent directory. If an import in new code says x/y/v2/z but1349// x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,1350// then go build will read the import as x/y/z instead.1351// See golang.org/issue/25069.1352func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) {1353	if parentRoot == "" {1354		return path1355	}13561357	// If there are no vN elements in path, leave it alone.1358	// (The code below would do the same, but only after1359	// some other file system accesses that we can avoid1360	// here by returning early.)1361	if i, _ := findVersionElement(path); i < 0 {1362		return path1363	}13641365	dir, root := dirAndRoot(parentPath, parentDir, parentRoot)13661367	// Consider dir and parents, up to and including root.1368	for i := len(dir); i >= len(root); i-- {1369		if i < len(dir) && dir[i] != filepath.Separator {1370			continue1371		}1372		if goModPath(dir[:i]) != "" {1373			goto HaveGoMod1374		}1375	}1376	// This code is not in a tree with a go.mod,1377	// so apply no changes to the path.1378	return path13791380HaveGoMod:1381	// This import is in a tree with a go.mod.1382	// Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z1383	// if GOPATH/src/x/y/go.mod says module "x/y/v2",13841385	// If x/y/v2/z exists, use it unmodified.1386	if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {1387		return path1388	}13891390	// Otherwise look for a go.mod supplying a version element.1391	// Some version-like elements may appear in paths but not1392	// be module versions; we skip over those to look for module1393	// versions. For example the module m/v2 might have a1394	// package m/v2/api/v1/foo.1395	limit := len(path)1396	for limit > 0 {1397		i, j := findVersionElement(path[:limit])1398		if i < 0 {1399			return path1400		}1401		if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {1402			if mpath := goModPath(bp.Dir); mpath != "" {1403				// Found a valid go.mod file, so we're stopping the search.1404				// If the path is m/v2/p and we found m/go.mod that says1405				// "module m/v2", then we return "m/p".1406				if mpath == path[:j] {1407					return path[:i] + path[j:]1408				}1409				// Otherwise just return the original path.1410				// We didn't find anything worth rewriting,1411				// and the go.mod indicates that we should1412				// not consider parent directories.1413				return path1414			}1415		}1416		limit = i1417	}1418	return path1419}14201421// hasGoFiles reports whether dir contains any files with names ending in .go.1422// For a vendor check we must exclude directories that contain no .go files.1423// Otherwise it is not possible to vendor just a/b/c and still import the1424// non-vendored a/b. See golang.org/issue/13832.1425func hasGoFiles(dir string) bool {1426	files, _ := os.ReadDir(dir)1427	for _, f := range files {1428		if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {1429			return true1430		}1431	}1432	return false1433}14341435// reusePackage reuses package p to satisfy the import at the top1436// of the import stack stk. If this use causes an import loop,1437// reusePackage updates p's error information to record the loop.1438func reusePackage(p *Package, stk *ImportStack) *Package {1439	// We use p.Internal.Imports==nil to detect a package that1440	// is in the midst of its own loadPackage call1441	// (all the recursion below happens before p.Internal.Imports gets set).1442	if p.Internal.Imports == nil {1443		if p.Error == nil {1444			p.Error = &PackageError{1445				ImportStack:   stk.Copy(),1446				Err:           errors.New("import cycle not allowed"),1447				IsImportCycle: true,1448			}1449		} else if !p.Error.IsImportCycle {1450			// If the error is already set, but it does not indicate that1451			// we are in an import cycle, set IsImportCycle so that we don't1452			// end up stuck in a loop down the road.1453			p.Error.IsImportCycle = true1454		}1455		p.Incomplete = true1456	}1457	// Don't rewrite the import stack in the error if we have an import cycle.1458	// If we do, we'll lose the path that describes the cycle.1459	if p.Error != nil && p.Error.ImportStack != nil &&1460		!p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack.Pkgs()) {1461		p.Error.ImportStack = stk.Copy()1462	}1463	return p1464}14651466// disallowInternal checks that srcDir (containing package importerPath, if non-empty)1467// is allowed to import p.1468// If the import is allowed, disallowInternal returns the original package p.1469// If not, it returns a new package containing just an appropriate error.1470func disallowInternal(ld *modload.Loader, ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *PackageError {1471	// golang.org/s/go14internal:1472	// An import of a path containing the element “internal”1473	// is disallowed if the importing code is outside the tree1474	// rooted at the parent of the “internal” directory.14751476	// There was an error loading the package; stop here.1477	if p.Error != nil {1478		return nil1479	}14801481	// The generated 'testmain' package is allowed to access testing/internal/...,1482	// as if it were generated into the testing directory tree1483	// (it's actually in a temporary directory outside any Go tree).1484	// This cleans up a former kludge in passing functionality to the testing package.1485	if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {1486		return nil1487	}14881489	// We can't check standard packages with gccgo.1490	if cfg.BuildContext.Compiler == "gccgo" && p.Standard {1491		return nil1492	}14931494	// The sort package depends on internal/reflectlite, but during bootstrap1495	// the path rewriting causes the normal internal checks to fail.1496	// Instead, just ignore the internal rules during bootstrap.1497	if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") {1498		return nil1499	}15001501	// importerPath is empty: we started1502	// with a name given on the command line, not an1503	// import. Anything listed on the command line is fine.1504	if importerPath == "" {1505		return nil1506	}15071508	// Check for "internal" element: three cases depending on begin of string and/or end of string.1509	i, ok := findInternal(p.ImportPath)1510	if !ok {1511		return nil1512	}15131514	// Internal is present.1515	// Map import path back to directory corresponding to parent of internal.1516	if i > 0 {1517		i-- // rewind over slash in ".../internal"1518	}15191520	// FIPS-140 snapshots are special, because they comes from a non-GOROOT1521	// directory, so the usual directory rules don't work apply, or rather they1522	// apply differently depending on whether we are using a snapshot or the1523	// in-tree copy of the code. We apply a consistent rule here:1524	// crypto/internal/fips140 can only see crypto/internal, never top-of-tree internal.1525	// Similarly, crypto/... can see crypto/internal/fips140 even though the usual rules1526	// would not allow it in snapshot mode.1527	if str.HasPathPrefix(importerPath, "crypto") && str.HasPathPrefix(p.ImportPath, "crypto/internal/fips140") {1528		return nil // crypto can use crypto/internal/fips1401529	}1530	if str.HasPathPrefix(importerPath, "crypto/internal/fips140") {1531		if str.HasPathPrefix(p.ImportPath, "crypto/internal") {1532			return nil // crypto/internal/fips140 can use crypto/internal1533		}1534		goto Error1535	}15361537	if p.Module == nil {1538		parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]15391540		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1541			return nil1542		}15431544		// Look for symlinks before reporting error.1545		srcDir = expandPath(srcDir)1546		parent = expandPath(parent)1547		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1548			return nil1549		}1550	} else {1551		// p is in a module, so make it available based on the importer's import path instead1552		// of the file path (https://golang.org/issue/23970).1553		if importer.Internal.CmdlineFiles {1554			// The importer is a list of command-line files.1555			// Pretend that the import path is the import path of the1556			// directory containing them.1557			// If the directory is outside the main modules, this will resolve to ".",1558			// which is not a prefix of any valid module.1559			importerPath, _ = ld.MainModules.DirImportPath(ld, ctx, importer.Dir)1560		}1561		parentOfInternal := p.ImportPath[:i]1562		if str.HasPathPrefix(importerPath, parentOfInternal) {1563			return nil1564		}1565	}15661567Error:1568	// Internal is present, and srcDir is outside parent's tree. Not allowed.1569	perr := &PackageError{1570		alwaysPrintStack: true,1571		ImportStack:      stk.Copy(),1572		Err:              ImportErrorf(p.ImportPath, "use of internal package %s not allowed", p.ImportPath),1573	}1574	return perr1575}15761577// findInternal looks for the final "internal" path element in the given import path.1578// If there isn't one, findInternal returns ok=false.1579// Otherwise, findInternal returns ok=true and the index of the "internal".1580func findInternal(path string) (index int, ok bool) {1581	// Three cases, depending on internal at start/end of string or not.1582	// The order matters: we must return the index of the final element,1583	// because the final one produces the most restrictive requirement1584	// on the importer.1585	switch {1586	case strings.HasSuffix(path, "/internal"):1587		return len(path) - len("internal"), true1588	case strings.Contains(path, "/internal/"):1589		return strings.LastIndex(path, "/internal/") + 1, true1590	case path == "internal", strings.HasPrefix(path, "internal/"):1591		return 0, true1592	}1593	return 0, false1594}15951596// disallowVendor checks that srcDir is allowed to import p as path.1597// If the import is allowed, disallowVendor returns the original package p.1598// If not, it returns a PackageError.1599func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *PackageError {1600	// If the importerPath is empty, we started1601	// with a name given on the command line, not an1602	// import. Anything listed on the command line is fine.1603	if importerPath == "" {1604		return nil1605	}16061607	if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != nil {1608		return perr1609	}16101611	// Paths like x/vendor/y must be imported as y, never as x/vendor/y.1612	if i, ok := FindVendor(path); ok {1613		perr := &PackageError{1614			ImportStack: stk.Copy(),1615			Err:         ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]),1616		}1617		return perr1618	}16191620	return nil1621}16221623// disallowVendorVisibility checks that srcDir is allowed to import p.1624// The rules are the same as for /internal/ except that a path ending in /vendor1625// is not subject to the rules, only subdirectories of vendor.1626// This allows people to have packages and commands named vendor,1627// for maximal compatibility with existing source trees.1628func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *PackageError {1629	// The stack does not include p.ImportPath.1630	// If there's nothing on the stack, we started1631	// with a name given on the command line, not an1632	// import. Anything listed on the command line is fine.1633	if importerPath == "" {1634		return nil1635	}16361637	// Check for "vendor" element.1638	i, ok := FindVendor(p.ImportPath)1639	if !ok {1640		return nil1641	}16421643	// Vendor is present.1644	// Map import path back to directory corresponding to parent of vendor.1645	if i > 0 {1646		i-- // rewind over slash in ".../vendor"1647	}1648	truncateTo := i + len(p.Dir) - len(p.ImportPath)1649	if truncateTo < 0 || len(p.Dir) < truncateTo {1650		return nil1651	}1652	parent := p.Dir[:truncateTo]1653	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1654		return nil1655	}16561657	// Look for symlinks before reporting error.1658	srcDir = expandPath(srcDir)1659	parent = expandPath(parent)1660	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1661		return nil1662	}16631664	// Vendor is present, and srcDir is outside parent's tree. Not allowed.16651666	perr := &PackageError{1667		ImportStack: stk.Copy(),1668		Err:         errors.New("use of vendored package not allowed"),1669	}1670	return perr1671}16721673// FindVendor looks for the last non-terminating "vendor" path element in the given import path.1674// If there isn't one, FindVendor returns ok=false.1675// Otherwise, FindVendor returns ok=true and the index of the "vendor".1676//1677// Note that terminating "vendor" elements don't count: "x/vendor" is its own package,1678// not the vendored copy of an import "" (the empty import path).1679// This will allow people to have packages or commands named vendor.1680// This may help reduce breakage, or it may just be confusing. We'll see.1681func FindVendor(path string) (index int, ok bool) {1682	// Two cases, depending on internal at start of string or not.1683	// The order matters: we must return the index of the final element,1684	// because the final one is where the effective import path starts.1685	switch {1686	case strings.Contains(path, "/vendor/"):1687		return strings.LastIndex(path, "/vendor/") + 1, true1688	case strings.HasPrefix(path, "vendor/"):1689		return 0, true1690	}1691	return 0, false1692}16931694type TargetDir int16951696const (1697	ToTool TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)1698	ToBin                   // to bin dir inside package root (default for non-cmd/*)1699)17001701// InstallTargetDir reports the target directory for installing the command p.1702func InstallTargetDir(p *Package) TargetDir {1703	if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {1704		switch p.ImportPath {1705		case "cmd/go", "cmd/gofmt":1706			return ToBin1707		}1708		return ToTool1709	}1710	return ToBin1711}17121713var cgoExclude = map[string]bool{1714	"runtime/cgo": true,1715}17161717var cgoSyscallExclude = map[string]bool{1718	"runtime/cgo":  true,1719	"runtime/race": true,1720	"runtime/msan": true,1721	"runtime/asan": true,1722}17231724var foldPath = make(map[string]string)17251726// exeFromImportPath returns an executable name1727// for a package using the import path.1728//1729// The executable name is the last element of the import path.1730// In module-aware mode, an additional rule is used on import paths1731// consisting of two or more path elements. If the last element is1732// a vN path element specifying the major version, then the1733// second last element of the import path is used instead.1734func (p *Package) exeFromImportPath() string {1735	_, elem := pathpkg.Split(p.ImportPath)1736	if cfg.ModulesEnabled {1737		// If this is example.com/mycmd/v2, it's more useful to1738		// install it as mycmd than as v2. See golang.org/issue/24667.1739		if elem != p.ImportPath && isVersionElement(elem) {1740			_, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))1741		}1742	}1743	return elem1744}17451746// exeFromFiles returns an executable name for a package1747// using the first element in GoFiles or CgoFiles collections without the prefix.1748//1749// Returns empty string in case of empty collection.1750func (p *Package) exeFromFiles() string {1751	var src string1752	if len(p.GoFiles) > 0 {1753		src = p.GoFiles[0]1754	} else if len(p.CgoFiles) > 0 {1755		src = p.CgoFiles[0]1756	} else {1757		return ""1758	}1759	_, elem := filepath.Split(src)1760	return elem[:len(elem)-len(".go")]1761}17621763// DefaultExecName returns the default executable name for a package1764func (p *Package) DefaultExecName() string {1765	if p.Internal.CmdlineFiles {1766		return p.exeFromFiles()1767	}1768	return p.exeFromImportPath()1769}17701771// The package used for rewriting "simd"1772const SimdBridgePkg = "simd/internal/bridge"17731774// hasSimd encodes the conditions under which the presence/absence of1775// imports of "simd" is interesting, i.e., if there is intrinsic1776// support, and hence some rewriting of AST to use the intrinsics.1777// This is used for both build and test (and perhaps in other contexts to1778// be discovered later).1779func hasSimd(imports []string) (hasSimd bool) {1780	if cfg.BuildContext.GOARCH == "wasm" || cfg.BuildContext.GOARCH == "amd64" || cfg.BuildContext.GOARCH == "arm64" {1781		for _, imp := range imports {1782			if imp == "simd" {1783				hasSimd = true1784			}1785		}1786	}1787	return1788}17891790// load populates p using information from bp, err, which should1791// be the result of calling build.Context.Import.1792// stk contains the import stack, not including path itself.1793func (p *Package) load(ld *modload.Loader, ctx context.Context, opts PackageOpts, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {1794	p.copyBuild(opts, bp)17951796	// The localPrefix is the path we interpret ./ imports relative to,1797	// if we support them at all (not in module mode!).1798	// Synthesized main packages sometimes override this.1799	if p.Internal.Local && !cfg.ModulesEnabled {1800		p.Internal.LocalPrefix = dirToImportPath(p.Dir)1801	}18021803	// setError sets p.Error if it hasn't already been set. We may proceed1804	// after encountering some errors so that 'go list -e' has more complete1805	// output. If there's more than one error, we should report the first.1806	setError := func(err error) {1807		if p.Error == nil {1808			p.Error = &PackageError{1809				ImportStack: stk.Copy(),1810				Err:         err,1811			}1812			p.Incomplete = true18131814			// Add the importer's position information if the import position exists, and1815			// the current package being examined is the importer.1816			// If we have not yet accepted package p onto the import stack,1817			// then the cause of the error is not within p itself: the error1818			// must be either in an explicit command-line argument,1819			// or on the importer side (indicated by a non-empty importPos).1820			top, ok := stk.Top()1821			if ok && path != top.Pkg && len(importPos) > 0 {1822				p.Error.setPos(importPos)1823			}1824		}1825	}18261827	if err != nil {1828		p.Incomplete = true1829		p.setLoadPackageDataError(err, path, stk, importPos)1830	}18311832	useBindir := p.Name == "main"1833	if !p.Standard {1834		switch cfg.BuildBuildmode {1835		case "c-archive", "c-shared", "plugin":1836			useBindir = false1837		}1838	}18391840	if useBindir {1841		elem := p.DefaultExecName() + cfg.ExeSuffix1842		full := filepath.Join(cfg.BuildContext.GOOS+"_"+cfg.BuildContext.GOARCH, elem)1843		if cfg.BuildContext.GOOS != runtime.GOOS || cfg.BuildContext.GOARCH != runtime.GOARCH {1844			// Install cross-compiled binaries to subdirectories of bin.1845			elem = full1846		}1847		if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {1848			p.Internal.Build.BinDir = modload.BinDir(ld)1849		}1850		if p.Internal.Build.BinDir != "" {1851			// Install to GOBIN or bin of GOPATH entry.1852			p.Target = filepath.Join(p.Internal.Build.BinDir, elem)1853			if !p.Goroot && strings.Contains(elem, string(filepath.Separator)) && cfg.GOBIN != "" {1854				// Do not create $GOBIN/goos_goarch/elem.1855				p.Target = ""1856				p.Internal.GobinSubdir = true1857			}1858		}1859		if InstallTargetDir(p) == ToTool {1860			// This is for 'go tool'.1861			// Override all the usual logic and force it into the tool directory.1862			if cfg.BuildToolchainName == "gccgo" {1863				p.Target = filepath.Join(build.ToolDir, elem)1864			} else {1865				p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)1866			}1867		}1868	} else if p.Internal.Local {1869		// Local import turned into absolute path.1870		// No permanent install target.1871		p.Target = ""1872	} else if p.Standard && cfg.BuildContext.Compiler == "gccgo" {1873		// gccgo has a preinstalled standard library that cmd/go cannot rebuild.1874		p.Target = ""1875	} else {1876		p.Target = p.Internal.Build.PkgObj1877		if cfg.BuildBuildmode == "shared" && p.Internal.Build.PkgTargetRoot != "" {1878			// TODO(matloob): This shouldn't be necessary, but the cmd/cgo/internal/testshared1879			// test fails without Target set for this condition. Figure out why and1880			// fix it.1881			p.Target = filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath+".a")1882		}1883		if cfg.BuildLinkshared && p.Internal.Build.PkgTargetRoot != "" {1884			// TODO(bcmills): The reliance on PkgTargetRoot implies that -linkshared does1885			// not work for any package that lacks a PkgTargetRoot — such as a non-main1886			// package in module mode. We should probably fix that.1887			targetPrefix := filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath)1888			p.Target = targetPrefix + ".a"1889			shlibnamefile := targetPrefix + ".shlibname"1890			shlib, err := os.ReadFile(shlibnamefile)1891			if err != nil && !os.IsNotExist(err) {1892				base.Fatalf("reading shlibname: %v", err)1893			}1894			if err == nil {1895				libname := strings.TrimSpace(string(shlib))1896				if cfg.BuildContext.Compiler == "gccgo" {1897					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)1898				} else {1899					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)1900				}1901			}1902		}1903	}19041905	// Build augmented import list to add implicit dependencies.1906	// Be careful not to add imports twice, just to avoid confusion.1907	importPaths := p.Imports1908	addImport := func(path string, forCompiler bool) {1909		for _, p := range importPaths {1910			if path == p {1911				return1912			}1913		}1914		importPaths = append(importPaths, path)1915		if forCompiler {1916			p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)1917		}1918	}19191920	allowInternalSimdImport := 01921	if hasSimd := hasSimd(p.Imports); hasSimd {1922		addImport(SimdBridgePkg, true)1923		allowInternalSimdImport = allowSimdInternalBridge1924	}19251926	if !opts.IgnoreImports {1927		// Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",1928		// except for certain packages, to avoid circular dependencies.1929		if p.UsesCgo() {1930			addImport("unsafe", true)1931		}1932		if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {1933			addImport("runtime/cgo", true)1934		}1935		if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {1936			addImport("syscall", true)1937		}19381939		// SWIG adds imports of some standard packages.1940		if p.UsesSwig() {1941			addImport("unsafe", true)1942			if cfg.BuildContext.Compiler != "gccgo" {1943				addImport("runtime/cgo", true)1944			}1945			addImport("syscall", true)1946			addImport("sync", true)19471948			// TODO: The .swig and .swigcxx files can use1949			// %go_import directives to import other packages.1950		}19511952		// The linker loads implicit dependencies.1953		if p.Name == "main" && !p.Internal.ForceLibrary {1954			ldDeps, err := LinkerDeps(ld, p)1955			if err != nil {1956				setError(err)1957				return1958			}1959			for _, dep := range ldDeps {1960				addImport(dep, false)1961			}1962		}1963	}19641965	// Check for case-insensitive collisions of import paths.1966	// If modifying, consider changing checkPathCollisions() in1967	// src/cmd/go/internal/modcmd/vendor.go1968	fold := str.ToFold(p.ImportPath)1969	if other := foldPath[fold]; other == "" {1970		foldPath[fold] = p.ImportPath1971	} else if other != p.ImportPath {1972		setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))1973		return1974	}19751976	if !SafeArg(p.ImportPath) {1977		setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))1978		return1979	}19801981	// Errors after this point are caused by this package, not the importing1982	// package. Pushing the path here prevents us from reporting the error1983	// with the position of the import declaration.1984	stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})1985	defer stk.Pop()19861987	if p.BinaryOnly {1988		setError(errors.New("binary-only packages are no longer supported"))1989	}19901991	pkgPath := p.ImportPath1992	if p.Internal.CmdlineFiles {1993		pkgPath = "command-line-arguments"1994	}1995	if cfg.ModulesEnabled {1996		p.Module = modload.PackageModuleInfo(ld, ctx, pkgPath)1997	}1998	p.DefaultGODEBUG = defaultGODEBUG(ld, p, nil, nil, nil)19992000	if !opts.SuppressEmbedFiles {

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.