internal/lsp/cache: tolerate analysis panics better
Panics in type error analyzers shouldn't block diagnostics.
Fixes golang/go#45075.
Change-Id: I897f0949551ab65276371f7ec8140ccb689e5a7b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/302533
Trust: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
(cherry picked from commit 9b614f5d7b6512434a7f3d9fbf83c23124fe7bed)
Reviewed-on: https://go-review.googlesource.com/c/tools/+/302689
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
diff --git a/gopls/go.mod b/gopls/go.mod
index 5fb54e3..abe531e 100644
--- a/gopls/go.mod
+++ b/gopls/go.mod
@@ -14,3 +14,5 @@
mvdan.cc/gofumpt v0.1.0
mvdan.cc/xurls/v2 v2.2.0
)
+
+replace golang.org/x/tools => ../
diff --git a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go
index 75ba7de..1d7cb09 100644
--- a/gopls/internal/regtest/diagnostics/diagnostics_test.go
+++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go
@@ -1862,3 +1862,30 @@
)
})
}
+
+// Tests golang/go#45075, a panic in fillreturns breaks diagnostics.
+func TestFillReturnsPanic(t *testing.T) {
+ // At tip, the panic no longer reproduces.
+ testenv.SkipAfterGo1Point(t, 16)
+ const files = `
+-- go.mod --
+module mod.com
+
+go 1.16
+-- main.go --
+package main
+
+
+func foo() int {
+ return x, nil
+}
+
+`
+ Run(t, files, func(t *testing.T, env *Env) {
+ env.OpenFile("main.go")
+ env.Await(
+ env.DiagnosticAtRegexpWithMessage("main.go", `return x`, "wrong number of return values"),
+ LogMatching(protocol.Error, `.*analysis fillreturns.*panicked.*`, 2),
+ )
+ })
+}
diff --git a/internal/lsp/cache/analysis.go b/internal/lsp/cache/analysis.go
index 92af4f1..19675af 100644
--- a/internal/lsp/cache/analysis.go
+++ b/internal/lsp/cache/analysis.go
@@ -212,7 +212,6 @@
}
defer func() {
if r := recover(); r != nil {
- event.Log(ctx, fmt.Sprintf("analysis panicked: %s", r), tag.Package.Of(pkg.ID()))
data.err = errors.Errorf("analysis %s for package %s panicked: %v", analyzer.Name, pkg.PkgPath(), r)
}
}()
@@ -408,7 +407,8 @@
var err error
errorAnalyzerDiag, err = s.Analyze(ctx, pkg.ID(), analyzers)
if err != nil {
- return nil, err
+ // Keep going: analysis failures should not block diagnostics.
+ event.Error(ctx, "type error analysis failed", err, tag.Package.Of(pkg.ID()))
}
}
diags := map[span.URI][]*source.Diagnostic{}