}
dir := filepath.Join(cfg.GOROOT, "src", path)
return module.Version{}, dir, nil
+ } else if pathIsStd && path == cfg.GOROOTsrc {
+ return module.Version{}, dir, errors.New("directory should not directly contain source files")
}
// -mod=vendor is special.
// It's not strictly necessary but helpful to keep the checks.
if modRoot != "" && dir == modRoot {
pkg = targetPrefix
+ if modRoot == cfg.GOROOTsrc {
+ // A package in GOROOT/src would have an empty path.
+ // Keep the path as cfg.GOROOTsrc. We'll report an error in Import.
+ // See golang.org/issue/36587.
+ pkg = modRoot
+ }
} else if modRoot != "" && strings.HasPrefix(dir, modRoot+string(filepath.Separator)) && !strings.Contains(dir[len(modRoot):], "@") {
suffix := filepath.ToSlash(dir[len(modRoot):])
if strings.HasPrefix(suffix, "/vendor/") {
--- /dev/null
+# Return an error if the user tries to list a go source file directly in $GOROOT/src.
+# Tests golang.org/issue/36587
+
+mkdir $WORK/fakegoroot/src
+mkdir $WORK/fakegopath/src
+
+env GOROOT=$WORK/fakegoroot
+env GOPATH=$WORK/fakegopath
+
+cp go.mod $GOROOT/src/go.mod
+cp foo.go $GOROOT/src/foo.go
+
+go env GOROOT
+stdout $WORK(/|\\)fakegoroot
+
+# switch to GOROOT/src
+cd $GOROOT/src
+
+# GO111MODULE=on,GOROOT
+env GO111MODULE=on
+! go list ./...
+stderr 'directory should not directly contain source files'
+go list -e .
+go list -f '{{if .Error}}{{.Error.Err}}{{end}}' -e ./...
+stdout 'directory should not directly contain source files'
+
+# GO111MODULE=off,GOROOT
+env GO111MODULE=off
+go list ./...
+[!windows] stdout _$WORK/fakegoroot/src
+[windows] stdout fakegoroot/src # On windows the ":" in the volume name is mangled
+
+# switch to GOPATH/src
+cp $WORK/gopath/src/foo.go $GOPATH/src/foo.go
+cd $GOPATH/src
+
+# GO111MODULE=off,GOPATH
+env GO111MODULE=off
+go list ./...
+
+-- go.mod --
+module g
+
+go 1.14
+-- foo.go --
+package foo
\ No newline at end of file