diff --git a/internal/imports/fix_test.go b/internal/imports/fix_test.go index 610b9d5591..8132954af5 100644 --- a/internal/imports/fix_test.go +++ b/internal/imports/fix_test.go @@ -7,6 +7,7 @@ package imports import ( "flag" "fmt" + "go/build" "path/filepath" "runtime" "strings" @@ -1538,6 +1539,39 @@ func TestFindStdlib(t *testing.T) { } } +// https://golang.org/issue/31814 +func TestStdlibNotPrefixed(t *testing.T) { + const input = `package p +var _ = bytes.Buffer +` + const want = `package p + +import "bytes" + +var _ = bytes.Buffer +` + // Force a scan of the stdlib. + savedStdlib := stdlib + defer func() { stdlib = savedStdlib }() + stdlib = map[string]map[string]bool{} + + testConfig{ + module: packagestest.Module{ + Name: "ignored.com", + }, + }.test(t, func(t *goimportTest) { + // Run in GOROOT/src so that the std module shows up in go list -m all. + t.env.WorkingDir = filepath.Join(t.env.GOROOT, "src") + got, err := t.processNonModule(filepath.Join(t.env.GOROOT, "src/x.go"), []byte(input), nil) + if err != nil { + t.Fatalf("Process() = %v", err) + } + if string(got) != want { + t.Errorf("Got:\n%s\nWant:\n%s", got, want) + } + }) +} + type testConfig struct { gopathOnly bool goPackagesIncompatible bool @@ -1609,6 +1643,11 @@ func (c testConfig) test(t *testing.T, fn func(*goimportTest)) { }, exported: exported, } + if it.env.GOROOT == "" { + // packagestest clears out GOROOT to work around https://golang.org/issue/32849, + // which isn't relevant here. Fill it back in so we can find the standard library. + it.env.GOROOT = build.Default.GOROOT + } fn(it) }) } diff --git a/internal/imports/mod.go b/internal/imports/mod.go index 551bae8985..387799bdac 100644 --- a/internal/imports/mod.go +++ b/internal/imports/mod.go @@ -313,7 +313,7 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) { // The rest of this function canonicalizes the packages using the results // of initializing the resolver from 'go list -m'. - res, err := r.canonicalize(info.nonCanonicalImportPath, info.dir, info.needsReplace) + res, err := r.canonicalize(root.Type, info.nonCanonicalImportPath, info.dir, info.needsReplace) if err != nil { return } @@ -335,7 +335,7 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) { continue } - res, err := r.canonicalize(info.nonCanonicalImportPath, info.dir, info.needsReplace) + res, err := r.canonicalize(gopathwalk.RootModuleCache, info.nonCanonicalImportPath, info.dir, info.needsReplace) if err != nil { continue } @@ -347,7 +347,15 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) { // canonicalize gets the result of canonicalizing the packages using the results // of initializing the resolver from 'go list -m'. -func (r *ModuleResolver) canonicalize(importPath, dir string, needsReplace bool) (res *pkg, err error) { +func (r *ModuleResolver) canonicalize(rootType gopathwalk.RootType, importPath, dir string, needsReplace bool) (res *pkg, err error) { + // Packages in GOROOT are already canonical, regardless of the std/cmd modules. + if rootType == gopathwalk.RootGOROOT { + return &pkg{ + importPathShort: importPath, + dir: dir, + }, nil + } + // Check if the directory is underneath a module that's in scope. if mod := r.findModuleByDir(dir); mod != nil { // It is. If dir is the target of a replace directive,