}
 
        // Is the package in the standard library?
-       if search.IsStandardImportPath(path) {
-               if goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
-                       dir := filepath.Join(cfg.GOROOT, "src", path)
-
-                       // If the main module is in the standard library, attribute its packages
-                       // to that module.
-                       switch Target.Path {
-                       case "cmd":
-                               if strings.HasPrefix(path, "cmd") {
-                                       return Target, dir, nil
-                               }
-                       case "std":
-                               if !strings.HasPrefix(path, "cmd") {
-                                       return Target, dir, nil
-                               }
+       if search.IsStandardImportPath(path) &&
+               goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
+               if targetInGorootSrc {
+                       if dir, ok := dirInModule(path, targetPrefix, ModRoot(), true); ok {
+                               return Target, dir, nil
                        }
-                       return module.Version{}, dir, nil
                }
+               dir := filepath.Join(cfg.GOROOT, "src", path)
+               return module.Version{}, dir, nil
        }
 
        // -mod=vendor is special.
        // Everything must be in the main module or the main module's vendor directory.
        if cfg.BuildMod == "vendor" {
-               mainDir, mainOK := dirInModule(path, Target.Path, ModRoot(), true)
+               mainDir, mainOK := dirInModule(path, targetPrefix, ModRoot(), true)
                vendorDir, vendorOK := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false)
                if mainOK && vendorOK {
                        return module.Version{}, "", fmt.Errorf("ambiguous import: found %s in multiple directories:\n\t%s\n\t%s", path, mainDir, vendorDir)
 
        "cmd/go/internal/mvs"
        "cmd/go/internal/renameio"
        "cmd/go/internal/search"
-       "cmd/go/internal/str"
        "encoding/json"
        "fmt"
        "go/build"
        excluded    map[module.Version]bool
        Target      module.Version
 
+       // targetPrefix is the path prefix for packages in Target, without a trailing
+       // slash. For most modules, targetPrefix is just Target.Path, but the
+       // standard-library module "std" has an empty prefix.
+       targetPrefix string
+
+       // targetInGorootSrc caches whether modRoot is within GOROOT/src.
+       // The "std" module is special within GOROOT/src, but not otherwise.
+       targetInGorootSrc bool
+
        gopath string
 
        CmdModInit   bool   // running 'go mod init'
        Init()
        if modRoot == "" {
                Target = module.Version{Path: "command-line-arguments"}
+               targetPrefix = "command-line-arguments"
                buildList = []module.Version{Target}
                return
        }
 // modFileToBuildList initializes buildList from the modFile.
 func modFileToBuildList() {
        Target = modFile.Module.Mod
-       if (str.HasPathPrefix(Target.Path, "std") || str.HasPathPrefix(Target.Path, "cmd")) &&
-               search.InDir(cwd, cfg.GOROOTsrc) == "" {
-               base.Fatalf("go: reserved module path %s not allow outside of GOROOT/src", Target.Path)
+       targetPrefix = Target.Path
+       if search.InDir(cwd, cfg.GOROOTsrc) != "" {
+               targetInGorootSrc = true
+               if Target.Path == "std" {
+                       targetPrefix = ""
+               }
        }
 
        list := []module.Version{Target}
 
                                                if strings.HasPrefix(suffix, "/vendor/") {
                                                        // TODO getmode vendor check
                                                        pkg = strings.TrimPrefix(suffix, "/vendor/")
-                                               } else if Target.Path == "std" {
+                                               } else if targetInGorootSrc && Target.Path == "std" {
                                                        // Don't add the prefix "std/" to packages in the "std" module.
                                                        // It's the one module path that isn't a prefix of its packages.
                                                        pkg = strings.TrimPrefix(suffix, "/")
        }
 
        if dir == modRoot {
-               return Target.Path
+               return targetPrefix
        }
        if strings.HasPrefix(dir, modRoot+string(filepath.Separator)) {
                suffix := filepath.ToSlash(dir[len(modRoot):])
                if strings.HasPrefix(suffix, "/vendor/") {
                        return strings.TrimPrefix(suffix, "/vendor/")
                }
-               return Target.Path + suffix
+               return targetPrefix + suffix
        }
        return "."
 }
        ld.tags = imports.Tags()
        ld.testRoots = LoadTests
 
-       switch Target.Path {
-       case "std", "cmd":
-               // Inside the "std" and "cmd" modules, we prefer to use the vendor directory
-               // unless the command explicitly changes the module graph.
-               // TODO(golang.org/issue/30240): Remove this special case.
-               if cfg.CmdName != "get" && !strings.HasPrefix(cfg.CmdName, "mod ") {
-                       ld.forceStdVendor = true
-               }
+       // Inside the "std" and "cmd" modules, we prefer to use the vendor directory
+       // unless the command explicitly changes the module graph.
+       if !targetInGorootSrc || (cfg.CmdName != "get" && !strings.HasPrefix(cfg.CmdName, "mod ")) {
+               ld.forceStdVendor = true
        }
 
        return ld
                return path
        }
 
-       if str.HasPathPrefix(parentPath, "cmd") && (Target.Path != "cmd" || ld.forceStdVendor) {
-               vendorPath := pathpkg.Join("cmd", "vendor", path)
-               if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil {
-                       return vendorPath
+       if str.HasPathPrefix(parentPath, "cmd") {
+               if ld.forceStdVendor || Target.Path != "cmd" {
+                       vendorPath := pathpkg.Join("cmd", "vendor", path)
+                       if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil {
+                               return vendorPath
+                       }
                }
-       }
-       if Target.Path != "std" || ld.forceStdVendor {
+       } else if ld.forceStdVendor || Target.Path != "std" {
                vendorPath := pathpkg.Join("vendor", path)
                if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil {
                        return vendorPath
                return vendorList, nil
        }
 
-       switch Target.Path {
-       case "std", "cmd":
+       if targetInGorootSrc {
                // When inside "std" or "cmd", only fetch and read go.mod files if we're
                // explicitly running a command that can change the module graph. If we have
                // to resolve a new dependency, we might pick the wrong version, but 'go mod
 
 // QueryPackage returns Target as the version.
 func QueryPackage(path, query string, allowed func(module.Version) bool) (module.Version, *modfetch.RevInfo, error) {
        if HasModRoot() {
-               if _, ok := dirInModule(path, Target.Path, modRoot, true); ok {
+               if _, ok := dirInModule(path, targetPrefix, modRoot, true); ok {
                        if query != "latest" {
                                return module.Version{}, nil, fmt.Errorf("can't query specific version (%q) for package %s in the main module (%s)", query, path, Target.Path)
                        }
 
 
        if cfg.BuildMod == "vendor" {
                if HasModRoot() {
-                       modPrefix := Target.Path
-                       if Target.Path == "std" {
-                               modPrefix = ""
-                       }
-                       walkPkgs(ModRoot(), modPrefix, false)
+                       walkPkgs(ModRoot(), targetPrefix, false)
                        walkPkgs(filepath.Join(ModRoot(), "vendor"), "", false)
                }
                return pkgs
                if !treeCanMatch(mod.Path) {
                        continue
                }
-               var root string
-               if mod.Version == "" {
+               var root, modPrefix string
+               if mod == Target {
                        if !HasModRoot() {
                                continue // If there is no main module, we can't search in it.
                        }
                        root = ModRoot()
+                       modPrefix = targetPrefix
                } else {
                        var err error
                        root, _, err = fetch(mod)
                                base.Errorf("go: %v", err)
                                continue
                        }
-               }
-               modPrefix := mod.Path
-               if mod.Path == "std" {
-                       modPrefix = ""
+                       modPrefix = mod.Path
                }
                walkPkgs(root, modPrefix, false)
        }
 
--- /dev/null
+env GO111MODULE=on
+
+# If the working directory is a different GOROOT, then the 'std' module should be
+# treated as an ordinary module (with an ordinary module prefix).
+# It should not override packages in GOROOT, but should not fail the command.
+# See golang.org/issue/30756.
+go list -e -deps -f '{{.ImportPath}} {{.Dir}}' ./bytes
+stdout ^std/bytes.*$PWD[/\\]bytes
+stdout '^bytes/modified'
+
+-- go.mod --
+module std
+
+go 1.12
+-- bytes/bytes.go --
+package bytes
+
+import _"bytes/modified"
+-- bytes/modified/modified.go --
+package modified