diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go index b3e9e04df1..b578bae2a0 100644 --- a/internal/lsp/cache/check.go +++ b/internal/lsp/cache/check.go @@ -11,6 +11,7 @@ import ( "go/ast" "go/token" "go/types" + "path" "sort" "sync" @@ -309,6 +310,24 @@ func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode sourc }, Importer: importerFunc(func(pkgPath string) (*types.Package, error) { dep := deps[packagePath(pkgPath)] + if dep == nil { + // We may be in GOPATH mode, in which case we need to check vendor dirs. + searchDir := path.Dir(pkg.PkgPath()) + for { + vdir := packagePath(path.Join(searchDir, "vendor", pkgPath)) + if vdep := deps[vdir]; vdep != nil { + dep = vdep + break + } + + // Search until Dir doesn't take us anywhere new, e.g. "." or "/". + next := path.Dir(searchDir) + if searchDir == next { + break + } + searchDir = next + } + } if dep == nil { return nil, errors.Errorf("no package for import %s", pkgPath) } diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go index 98b083a9fe..12839d6377 100644 --- a/internal/lsp/cache/load.go +++ b/internal/lsp/cache/load.go @@ -42,6 +42,9 @@ func (s *snapshot) load(ctx context.Context, scopes ...interface{}) ([]*metadata for _, scope := range scopes { switch scope := scope.(type) { case []packagePath: + // The only time we pass package paths is when we're doing a + // partial workspace load. In those cases, the paths came back from + // go list and should already be GOPATH-vendorized when appropriate. for _, p := range scope { query = append(query, string(p)) } @@ -59,6 +62,8 @@ func (s *snapshot) load(ctx context.Context, scopes ...interface{}) ([]*metadata q = "./..." } query = append(query, q) + default: + panic(fmt.Sprintf("unknown scope type %T", scope)) } } ctx, done := trace.StartSpan(ctx, "cache.view.load", telemetry.Query.Of(query))