internal/memoize: add an error return to (*handle).Get

Fixes golang/go#36004

Change-Id: I8da7c21eaa9cf6ffac12aabdd6803d06781cef32
Reviewed-on: https://go-review.googlesource.com/c/tools/+/239564
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/internal/lsp/cache/analysis.go b/internal/lsp/cache/analysis.go
index 35336a7..ba5fb39 100644
--- a/internal/lsp/cache/analysis.go
+++ b/internal/lsp/cache/analysis.go
@@ -152,9 +152,9 @@
 }
 
 func (act *actionHandle) analyze(ctx context.Context) ([]*source.Error, interface{}, error) {
-	v := act.handle.Get(ctx)
+	v, err := act.handle.Get(ctx)
 	if v == nil {
-		return nil, nil, ctx.Err()
+		return nil, nil, err
 	}
 	data, ok := v.(*actionData)
 	if !ok {
@@ -182,9 +182,9 @@
 	for _, act := range actions {
 		act := act
 		g.Go(func() error {
-			v := act.handle.Get(ctx)
-			if v == nil {
-				return errors.Errorf("no analyses for %s", act.pkg.ID())
+			v, err := act.handle.Get(ctx)
+			if err != nil {
+				return err
 			}
 			data, ok := v.(*actionData)
 			if !ok {
diff --git a/internal/lsp/cache/cache.go b/internal/lsp/cache/cache.go
index 8a72479..9ae3295 100644
--- a/internal/lsp/cache/cache.go
+++ b/internal/lsp/cache/cache.go
@@ -72,9 +72,9 @@
 	h := c.store.Bind(key, func(ctx context.Context) interface{} {
 		return readFile(ctx, uri, modTime)
 	})
-	v := h.Get(ctx)
-	if v == nil {
-		return nil, ctx.Err()
+	v, err := h.Get(ctx)
+	if err != nil {
+		return nil, err
 	}
 	return v.(*fileHandle), nil
 }
diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go
index 5c7d5f1..3ab5b3f 100644
--- a/internal/lsp/cache/check.go
+++ b/internal/lsp/cache/check.go
@@ -190,9 +190,9 @@
 }
 
 func (ph *packageHandle) check(ctx context.Context) (*pkg, error) {
-	v := ph.handle.Get(ctx)
-	if v == nil {
-		return nil, ctx.Err()
+	v, err := ph.handle.Get(ctx)
+	if err != nil {
+		return nil, err
 	}
 	data := v.(*packageData)
 	return data.pkg, data.err
diff --git a/internal/lsp/cache/mod.go b/internal/lsp/cache/mod.go
index bcd04f5..c0f98f9 100644
--- a/internal/lsp/cache/mod.go
+++ b/internal/lsp/cache/mod.go
@@ -55,9 +55,9 @@
 }
 
 func (mh *parseModHandle) Parse(ctx context.Context) (*modfile.File, *protocol.ColumnMapper, []source.Error, error) {
-	v := mh.handle.Get(ctx)
-	if v == nil {
-		return nil, nil, nil, ctx.Err()
+	v, err := mh.handle.Get(ctx)
+	if err != nil {
+		return nil, nil, nil, err
 	}
 	data := v.(*parseModData)
 	return data.parsed, data.m, data.parseErrors, data.err
@@ -200,9 +200,9 @@
 }
 
 func (mwh *modWhyHandle) Why(ctx context.Context) (map[string]string, error) {
-	v := mwh.handle.Get(ctx)
-	if v == nil {
-		return nil, ctx.Err()
+	v, err := mwh.handle.Get(ctx)
+	if err != nil {
+		return nil, err
 	}
 	data := v.(*modWhyData)
 	return data.why, data.err
@@ -287,9 +287,9 @@
 }
 
 func (muh *modUpgradeHandle) Upgrades(ctx context.Context) (map[string]string, error) {
-	v := muh.handle.Get(ctx)
+	v, err := muh.handle.Get(ctx)
 	if v == nil {
-		return nil, ctx.Err()
+		return nil, err
 	}
 	data := v.(*modUpgradeData)
 	return data.upgrades, data.err
diff --git a/internal/lsp/cache/mod_tidy.go b/internal/lsp/cache/mod_tidy.go
index 485b16b..d00f36f 100644
--- a/internal/lsp/cache/mod_tidy.go
+++ b/internal/lsp/cache/mod_tidy.go
@@ -49,9 +49,9 @@
 }
 
 func (mth *modTidyHandle) Tidy(ctx context.Context) (map[string]*modfile.Require, []source.Error, error) {
-	v := mth.handle.Get(ctx)
-	if v == nil {
-		return nil, nil, ctx.Err()
+	v, err := mth.handle.Get(ctx)
+	if err != nil {
+		return nil, nil, err
 	}
 	data := v.(*modTidyData)
 	return data.missingDeps, data.diagnostics, data.err
diff --git a/internal/lsp/cache/parse.go b/internal/lsp/cache/parse.go
index 46aea45..a3b1427 100644
--- a/internal/lsp/cache/parse.go
+++ b/internal/lsp/cache/parse.go
@@ -91,7 +91,10 @@
 }
 
 func (pgh *parseGoHandle) parse(ctx context.Context) (*parseGoData, error) {
-	v := pgh.handle.Get(ctx)
+	v, err := pgh.handle.Get(ctx)
+	if err != nil {
+		return nil, err
+	}
 	data, ok := v.(*parseGoData)
 	if !ok {
 		return nil, errors.Errorf("no parsed file for %s", pgh.File().URI())
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index f04a988..8faab5b 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -280,9 +280,9 @@
 	if v.builtin == nil {
 		return nil, errors.Errorf("no builtin package for view %s", v.name)
 	}
-	data := v.builtin.handle.Get(ctx)
-	if ctx.Err() != nil {
-		return nil, ctx.Err()
+	data, err := v.builtin.handle.Get(ctx)
+	if err != nil {
+		return nil, err
 	}
 	if data == nil {
 		return nil, errors.Errorf("unexpected nil builtin package")
diff --git a/internal/memoize/memoize.go b/internal/memoize/memoize.go
index 30f4c0c..595d438 100644
--- a/internal/memoize/memoize.go
+++ b/internal/memoize/memoize.go
@@ -203,9 +203,9 @@
 // If the value is not yet ready, the underlying function will be invoked.
 // This activates the handle, and it will remember the value for as long as it exists.
 // If ctx is cancelled, Get returns nil.
-func (h *Handle) Get(ctx context.Context) interface{} {
+func (h *Handle) Get(ctx context.Context) (interface{}, error) {
 	if ctx.Err() != nil {
-		return nil
+		return nil, ctx.Err()
 	}
 	h.mu.Lock()
 	switch h.state {
@@ -215,14 +215,14 @@
 		return h.wait(ctx)
 	case stateCompleted:
 		defer h.mu.Unlock()
-		return h.value
+		return h.value, nil
 	default:
 		panic("unknown state")
 	}
 }
 
 // run starts h.function and returns the result. h.mu must be locked.
-func (h *Handle) run(ctx context.Context) interface{} {
+func (h *Handle) run(ctx context.Context) (interface{}, error) {
 	childCtx, cancel := context.WithCancel(xcontext.Detach(ctx))
 	h.cancel = cancel
 	h.state = stateRunning
@@ -258,7 +258,7 @@
 }
 
 // wait waits for the value to be computed, or ctx to be cancelled. h.mu must be locked.
-func (h *Handle) wait(ctx context.Context) interface{} {
+func (h *Handle) wait(ctx context.Context) (interface{}, error) {
 	h.waiters++
 	done := h.done
 	h.mu.Unlock()
@@ -268,9 +268,9 @@
 		h.mu.Lock()
 		defer h.mu.Unlock()
 		if h.state == stateCompleted {
-			return h.value
+			return h.value, nil
 		}
-		return nil
+		return nil, nil
 	case <-ctx.Done():
 		h.mu.Lock()
 		defer h.mu.Unlock()
@@ -282,7 +282,7 @@
 			h.done = nil
 			h.cancel = nil
 		}
-		return nil
+		return nil, ctx.Err()
 	}
 }
 
diff --git a/internal/memoize/memoize_test.go b/internal/memoize/memoize_test.go
index 1ac0513..305b594 100644
--- a/internal/memoize/memoize_test.go
+++ b/internal/memoize/memoize_test.go
@@ -217,8 +217,11 @@
 	fmt.Fprintf(w, "start %v\n", name)
 	value := ""
 	for _, key := range keys {
-		v := asValue(s.Bind(key, generate(s, key)).Get(ctx))
-		if v == nil {
+		i, err := s.Bind(key, generate(s, key)).Get(ctx)
+		if err != nil {
+			return &stringOrError{err: err}
+		}
+		if v := asValue(i); v == nil {
 			value = value + " <nil>"
 		} else if v.err != nil {
 			value = value + " !" + v.err.Error()