internal/lsp: fix go.mod creation without experimental workspace module

We were previously adding modules to the snapshot, even if they weren't
relevant without the workspace module mode. Now, check that the modules
are relevant before adding them.

Change-Id: Ib7600482992d538db2f7451863fee5709a35ffb3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/258719
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/diagnostics_test.go b/gopls/internal/regtest/diagnostics_test.go
index 2d70f40..0291f2c 100644
--- a/gopls/internal/regtest/diagnostics_test.go
+++ b/gopls/internal/regtest/diagnostics_test.go
@@ -280,6 +280,23 @@
 			)
 		})
 	})
+
+	t.Run("without workspace module", func(t *testing.T) {
+		withOptions(EditorConfig{
+			WithoutExperimentalWorkspaceModule: true,
+		}).run(t, noMod, func(t *testing.T, env *Env) {
+			env.Await(
+				env.DiagnosticAtRegexp("main.go", `"mod.com/bob"`),
+			)
+			if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}); err != nil {
+				t.Fatal(err)
+			}
+			env.Await(
+				EmptyDiagnostics("main.go"),
+				env.DiagnosticAtRegexp("bob/bob.go", "x"),
+			)
+		})
+	})
 }
 
 // Tests golang/go#38267.
diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go
index 44792f2..e597873 100644
--- a/internal/lsp/cache/session.go
+++ b/internal/lsp/cache/session.go
@@ -254,8 +254,9 @@
 	if !options.ExperimentalWorkspaceModule {
 		path := filepath.Join(root.Filename(), "go.mod")
 		if info, _ := os.Stat(path); info != nil {
-			m := newModule(ctx, span.URIFromPath(path))
-			modules[m.rootURI] = m
+			if m := getViewModule(ctx, root, span.URIFromPath(path), options); m != nil {
+				modules[m.rootURI] = m
+			}
 		}
 		return modules, nil
 	}
@@ -277,8 +278,9 @@
 		}
 		// We're only interested in go.mod files.
 		if filepath.Base(path) == "go.mod" {
-			m := newModule(ctx, span.URIFromPath(path))
-			modules[m.rootURI] = m
+			if m := getViewModule(ctx, root, span.URIFromPath(path), options); m != nil {
+				modules[m.rootURI] = m
+			}
 		}
 		return nil
 	})
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index d08bc78..4697bb3 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -1077,8 +1077,11 @@
 			rootURI := span.URIFromPath(filepath.Dir(withoutURI.Filename()))
 			if currentMod {
 				if _, ok := result.modules[rootURI]; !ok {
-					result.modules[rootURI] = newModule(ctx, currentFH.URI())
-					shouldReinitializeView = true
+					if m := getViewModule(ctx, s.view.rootURI, currentFH.URI(), s.view.options); m != nil {
+						result.modules[m.rootURI] = m
+						shouldReinitializeView = true
+					}
+
 				}
 			} else if originalMod {
 				// Similarly, we need to retry the IWL if a go.mod in the workspace
@@ -1574,8 +1577,15 @@
 	return file, nil
 }
 
-func newModule(ctx context.Context, modURI span.URI) *moduleRoot {
+func getViewModule(ctx context.Context, viewRootURI, modURI span.URI, options *source.Options) *moduleRoot {
 	rootURI := span.URIFromPath(filepath.Dir(modURI.Filename()))
+	// If we are not in multi-module mode, check that the affected module is
+	// in the workspace root.
+	if !options.ExperimentalWorkspaceModule {
+		if span.CompareURI(rootURI, viewRootURI) != 0 {
+			return nil
+		}
+	}
 	sumURI := span.URIFromPath(sumFilename(modURI))
 	if info, _ := os.Stat(sumURI.Filename()); info == nil {
 		sumURI = ""