golang/go

x/tools/gopls: Hover: panic in lookup{ObjectByName,DocLinkSymbol}

Closed this issue · 20 comments

#!stacks
("bug.Reportf" || "runtime.sigpanic") &&
   ("lookupObjectByName" || "lookupDocLinkSymbol")

Issue created by stacks.

func lookupObjectByName(pkg *cache.Package, pgf *parsego.File, name string) types.Object {
	scope := pkg.Types().Scope()
	fileScope := pkg.TypesInfo().Scopes[pgf.File]
	pkgName, suffix, _ := strings.Cut(name, ".")
	obj, ok := fileScope.Lookup(pkgName).(*types.PkgName) // <--- panic

Variant after the function was renamed:

func lookupDocLinkSymbol(pkg *cache.Package, pgf *parsego.File, name string) types.Object {
	scope := pkg.Types().Scope()

	prefix, suffix, _ := strings.Cut(name, ".")

	// Try treating the prefix as a package name,
	// allowing for non-renaming and renaming imports.
	fileScope := pkg.TypesInfo().Scopes[pgf.File]
	if fileScope == nil {
		// This is theoretically possible if pgf is a GoFile but not a
		// CompiledGoFile. However, we do not know how to produce such a package
		// without using an external GoPackagesDriver.
		// See if this is the source of golang/go#70635
		if slices.Contains(pkg.CompiledGoFiles(), pgf) {
			bug.Reportf("missing file scope for compiled file")  //  <--- reached
		} else {
			bug.Reportf("missing file scope for non-compiled file")
		}

This stack l9BGAQ was reported by telemetry:

golang.org/x/tools/gopls@v0.16.1 go1.23.0 linux/amd64 vscode (1)

Dups: z79pXw p3-DZQ oHmaZg 5F-J2A UxUyAQ 1qaY1Q 7fS6aA jVkbpg wt4MLQ 9Xt7NQ z93tjA

This is mysterious. The crash is in go/types.(*Scope).Lookup on this line:

func (s *Scope) Lookup(name string) Object {
	obj := resolve(name, s.elems[name])
	if obj == universeAnyAlias && !aliasAny() { // <---------- panic
		return universeAnyNoAlias
	}
	return obj
}

but the only way that line can panic (short of a compiler error that causes the wrong line to be reported) is if obj is a types.Object value of the same concrete type as universeAnyAlias and that concrete type does not support == comparison. However, universeAnyAlias clearly has type *TypeName, a pointer, which supports == comparison. (And presumably resolve also returns only pointers to various struct types).

I do not understand how this crash is possible, and so suggest that we move it to the next milestone and see if it reoccurs in v0.17.0.

@dr2chase Got any ideas how this crash could possibly occur?

Change https://go.dev/cl/633095 mentions this issue: gopls/internal/golang: avoid crash in lookupDocLinkSymbol

Change https://go.dev/cl/633707 mentions this issue: gopls/internal/golang: avoid crash in lookupDocLinkSymbol

I was just looking through my telemetry data, and saw that I encountered this crash 3 times on 12/2 (I hadn't noticed the crashes), so it must be reachable without a GOPACKAGESDRIVER.

Unfortunately, logs were lost.

No time to look into this one. Bumping to v0.18.1.

Change https://go.dev/cl/684615 mentions this issue: gopls/internal/golang: reproduce various edge cases of issue 69616