internal/lsp/cache: validate the range for critical errors in go files
This avoids the panic reported in golang/go#54395.
Fixes golang/go#54395
Change-Id: Ief35985a503d3cc13971499dc6f4e9c1d1d63ea3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/422894
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/regtest/workspace/broken_test.go
index fbc41de..b06c155 100644
--- a/gopls/internal/regtest/workspace/broken_test.go
+++ b/gopls/internal/regtest/workspace/broken_test.go
@@ -186,6 +186,8 @@
go 1.12
-- a/a.go --
package a
+-- a/empty.go --
+// an empty file
-- b/go.mod --
module b.com
@@ -202,6 +204,7 @@
ver := env.GoVersion()
msg := msgForVersion(ver)
env.OpenFile("a/a.go")
+ env.OpenFile("a/empty.go")
env.OpenFile("b/go.mod")
env.Await(
env.DiagnosticAtRegexp("a/a.go", "package a"),
diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go
index 7f30939..b15c537 100644
--- a/internal/lsp/cache/load.go
+++ b/internal/lsp/cache/load.go
@@ -380,9 +380,12 @@
switch s.view.FileKind(fh) {
case source.Go:
if pgf, err := s.ParseGo(ctx, fh, source.ParseHeader); err == nil {
- pkgDecl := span.NewRange(pgf.Tok, pgf.File.Package, pgf.File.Name.End())
- if spn, err := pkgDecl.Span(); err == nil {
- rng, _ = pgf.Mapper.Range(spn)
+ // Check that we have a valid `package foo` range to use for positioning the error.
+ if pgf.File.Package.IsValid() && pgf.File.Name != nil && pgf.File.Name.End().IsValid() {
+ pkgDecl := span.NewRange(pgf.Tok, pgf.File.Package, pgf.File.Name.End())
+ if spn, err := pkgDecl.Span(); err == nil {
+ rng, _ = pgf.Mapper.Range(spn)
+ }
}
}
case source.Mod: