go/packages: fix bug in contains for ad-hoc packages

The test was wrong and the code was wrong.

Change-Id: I4ffe4bb4788912210b307a06e168629c6800d0fb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/184043
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/go/packages/golist.go b/go/packages/golist.go
index 320d566..00e21a7 100644
--- a/go/packages/golist.go
+++ b/go/packages/golist.go
@@ -230,8 +230,10 @@
 			return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
 		}
 		dirResponse, err := driver(cfg, pattern)
-		if err != nil {
-			// Couldn't find a package for the directory. Try to load the file as an ad-hoc package.
+		if err != nil || (len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].Errors) == 1) {
+			// There was an error loading the package. Try to load the file as an ad-hoc package.
+			// Usually the error will appear in a returned package, but may not if we're in modules mode
+			// and the ad-hoc is located outside a module.
 			var queryErr error
 			dirResponse, queryErr = driver(cfg, query)
 			if queryErr != nil {
diff --git a/go/packages/packages.go b/go/packages/packages.go
index cd15146..f20e444 100644
--- a/go/packages/packages.go
+++ b/go/packages/packages.go
@@ -527,28 +527,32 @@
 		lpkg.color = grey
 		stack = append(stack, lpkg) // push
 		stubs := lpkg.Imports       // the structure form has only stubs with the ID in the Imports
-		lpkg.Imports = make(map[string]*Package, len(stubs))
-		for importPath, ipkg := range stubs {
-			var importErr error
-			imp := ld.pkgs[ipkg.ID]
-			if imp == nil {
-				// (includes package "C" when DisableCgo)
-				importErr = fmt.Errorf("missing package: %q", ipkg.ID)
-			} else if imp.color == grey {
-				importErr = fmt.Errorf("import cycle: %s", stack)
-			}
-			if importErr != nil {
-				if lpkg.importErrors == nil {
-					lpkg.importErrors = make(map[string]error)
+		// If NeedImports isn't set, the imports fields will all be zeroed out.
+		// If NeedDeps isn't also set we want to keep the stubs.
+		if ld.Mode&NeedImports != 0 && ld.Mode&NeedDeps != 0 {
+			lpkg.Imports = make(map[string]*Package, len(stubs))
+			for importPath, ipkg := range stubs {
+				var importErr error
+				imp := ld.pkgs[ipkg.ID]
+				if imp == nil {
+					// (includes package "C" when DisableCgo)
+					importErr = fmt.Errorf("missing package: %q", ipkg.ID)
+				} else if imp.color == grey {
+					importErr = fmt.Errorf("import cycle: %s", stack)
 				}
-				lpkg.importErrors[importPath] = importErr
-				continue
-			}
+				if importErr != nil {
+					if lpkg.importErrors == nil {
+						lpkg.importErrors = make(map[string]error)
+					}
+					lpkg.importErrors[importPath] = importErr
+					continue
+				}
 
-			if visit(imp) {
-				lpkg.needsrc = true
+				if visit(imp) {
+					lpkg.needsrc = true
+				}
+				lpkg.Imports[importPath] = imp.Package
 			}
-			lpkg.Imports[importPath] = imp.Package
 		}
 		if lpkg.needsrc {
 			srcPkgs = append(srcPkgs, lpkg)
diff --git a/go/packages/packages_test.go b/go/packages/packages_test.go
index 43e68b7..bd86d95 100644
--- a/go/packages/packages_test.go
+++ b/go/packages/packages_test.go
@@ -1912,7 +1912,7 @@
 	}()
 
 	exported.Config.Mode = packages.NeedImports | packages.NeedFiles
-	pkgs, err := packages.Load(exported.Config, filename)
+	pkgs, err := packages.Load(exported.Config, "file="+filename)
 	if err != nil {
 		t.Fatal(err)
 	}