internal/lsp/cache: don't panic in Snapshot on a shutdown view

There are many places where we may use a view asynchronously while it is
shutting down. In these cases, it should be fine to fail or skip the
view when we fail to acquire its snapshot.

Fixes golang/go#56466

Change-Id: Icc4edfc1b951c40c8aa42a18ba4ecbf85621523d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/462820
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go
index 0eef84e..51d7a79 100644
--- a/gopls/internal/lsp/cache/snapshot.go
+++ b/gopls/internal/lsp/cache/snapshot.go
@@ -43,7 +43,16 @@
 type snapshot struct {
 	sequenceID uint64
 	globalID   source.GlobalSnapshotID
-	view       *View
+
+	// TODO(rfindley): the snapshot holding a reference to the view poses
+	// lifecycle problems: a view may be shut down and waiting for work
+	// associated with this snapshot to complete. While most accesses of the view
+	// are benign (options or workspace information), this is not formalized and
+	// it is wrong for the snapshot to use a shutdown view.
+	//
+	// Fix this by passing options and workspace information to the snapshot,
+	// both of which should be immutable for the snapshot.
+	view *View
 
 	cancel        func()
 	backgroundCtx context.Context