#!stacks
"sigpanic" && "inlineVariableOne-range1"
Issue created by stacks.
id := curIdent.Node().(*ast.Ident)
obj1 := info.Uses[id]
_, obj2 := scope.LookupParent(id.Name, pos)
if obj1 != obj2 {
return nil, nil, fmt.Errorf("cannot inline variable: its initializer expression refers to %q, which is shadowed by the declaration at line %d", id.Name, safetoken.Position(pgf.Tok, obj2.Pos()).Line) // <----------- obj2 is nil
}
This stack tdbvkw
was reported by telemetry:
crash/crash
runtime.gopanic:+69,+0x14f
runtime.panicmem:=262,+0x2e7
runtime.sigpanic:+19,+0x2b8
golang.org/x/tools/gopls/internal/golang.inlineVariableOne-range1:+8,+0x124
golang.org/x/tools/go/ast/inspector.Cursor.Preorder.func1:+6,+0xbb
golang.org/x/tools/gopls/internal/golang.inlineVariableOne:+13,+0x28f
golang.org/x/tools/gopls/internal/golang.ApplyFix.singleFile.func6:+1,+0x33
golang.org/x/tools/gopls/internal/golang.ApplyFix:+43,+0x6db
golang.org/x/tools/gopls/internal/server.(*commandHandler).ApplyFix.func1:+1,+0x67
golang.org/x/tools/gopls/internal/server.(*commandHandler).run.func2:+3,+0x6f
golang.org/x/tools/gopls/internal/server.(*commandHandler).run:+81,+0x407
golang.org/x/tools/gopls/internal/server.(*commandHandler).ApplyFix:+2,+0x11b
golang.org/x/tools/gopls/internal/protocol/command.Dispatch:+31,+0x907
golang.org/x/tools/gopls/internal/server.(*server).ResolveCodeAction:+21,+0x167
golang.org/x/tools/gopls/internal/protocol.serverDispatch:+46,+0xa5b
golang.org/x/tools/gopls/internal/lsprpc.(*streamServer).ServeStream.ServerHandler.func4:+5,+0x6f
golang.org/x/tools/gopls/internal/lsprpc.(*streamServer).ServeStream.handshaker.func5:+52,+0x637
golang.org/x/tools/gopls@v0.19.1 go1.25rc1 darwin/arm64 other,vscode (3)
Dups: BPia1w
Comment From: adonovan
The faulting instruction is the retrieval of obj2.Pos from the types.Object itable, meaning that obj2 is nil or invalid. (Yay for PC values!) If obj2 is nil, this means obj1 is non-nil, so we must have an input of the form:
func f(y int) {
var x = y // y is a valid reference (to obj1)
{
y := 2
println(x) <-- invoke inline-variable on x
_ = y
}
}
but somehow the LookupParent("y") operation at println(x)
fails to find any object. I don't see how this can happen, because the environment at that point must define a superset of the names defined at var x = y
. So this cannot happen.
Therefore, this must be caused by memory corruption of obj2. Ugh, I hate this.
Comment From: adonovan
Having just written "this cannot happen", like a bull to a red flag I sought to disprove myself, and did so easily: what if the set of free names that we loop over is too large, and includes names that are not free? This seems easily possible. Example:
func f() {
var x = func(notfree int) { _ = notfree }
println(x) <-- invoke inline-variable on x
}
Lo and behold gopls crashes. Not memory corruption, just bad code. Yay.
Comment From: gopherbot
Change https://go.dev/cl/683535 mentions this issue: gopls/internal/golang: fix crash in refactor.inline.variable
Comment From: gabyhelp
Related Issues
- x/tools/gopls: ChangeSignature: OOB panic in inlineCall (FuncType.Params inconsistent with Signature) #73912
- x/tools/internal/refactor/inline: panic in needsParens #71486 (closed)
- x/tools/gopls: ChangeSignature: crash in in inliner (likely due to ill-formed variadic call) #73187
- x/tools/gopls: ChangeSignature: OOB panic in inline.updateCalleeParams (mismatched syntactic/semantic params) #73913
- x/tools/gopls: Implementation (by signatures): nil panic in dynamicFuncCallType #74305 (closed)
- x/tools/gopls: nil deref in x/telemetry/internal/counter.(*Counter).add #73890
- x/tools/gopls: "inline: corrupted reference %v" bug in golang.RemoveUnusedParameter #69896 (closed)
- x/tools/gopls: Hover: invalid nil entry in types.Defs map #69362 (closed)
- x/tools/gopls: nil deref in 'go vendor' Snapshot.GoCommandInvocation #73891
- x/tools/gopls: ChangeSignature: "cannot inline: corrupted reference" bug #73779
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: adonovan
This stack BPia1w
was reported by telemetry:
crash/crash
runtime.gopanic:+69,+0x167
runtime.panicmem:=262,+0x358
runtime.sigpanic:+19,+0x328
golang.org/x/tools/gopls/internal/golang.inlineVariableOne-range1:+8,+0x177
golang.org/x/tools/go/ast/inspector.Cursor.Preorder.func1:+6,+0xab
golang.org/x/tools/gopls/internal/golang.inlineVariableOne:+13,+0x37a
golang.org/x/tools/gopls/internal/golang.ApplyFix.singleFile.func6:+1,+0x23
golang.org/x/tools/gopls/internal/golang.ApplyFix:+43,+0x702
golang.org/x/tools/gopls/internal/server.(*commandHandler).ApplyFix.func1:+1,+0x85
golang.org/x/tools/gopls/internal/server.(*commandHandler).run.func2:+3,+0x86
golang.org/x/tools/gopls/internal/server.(*commandHandler).run:+81,+0x582
golang.org/x/tools/gopls/internal/server.(*commandHandler).ApplyFix:+2,+0x19c
golang.org/x/tools/gopls/internal/protocol/command.Dispatch:+31,+0xac1
golang.org/x/tools/gopls/internal/server.(*server).ResolveCodeAction:+21,+0x1b8
golang.org/x/tools/gopls/internal/protocol.serverDispatch:+46,+0xcf9
golang.org/x/tools/gopls/internal/lsprpc.(*streamServer).ServeStream.ServerHandler.func4:+5,+0x84
golang.org/x/tools/gopls/internal/lsprpc.(*streamServer).ServeStream.handshaker.func5:+52,+0x908
golang.org/x/tools/gopls@v0.19.1 go1.24.4 linux/amd64 other (1)