Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls/internal/lsp/source: different hover for same type #47098

Closed
katsusan opened this issue Jul 8, 2021 · 6 comments
Closed

x/tools/gopls/internal/lsp/source: different hover for same type #47098

katsusan opened this issue Jul 8, 2021 · 6 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@katsusan
Copy link

katsusan commented Jul 8, 2021

What version of Go are you using (go version)?

➜  ~ go version
go version go1.16.5 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
➜  ~ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.5"
GCCGO="/usr/local/bin/gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3210144513=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Version of gopls:

➜  ~ gopls version
golang.org/x/tools/gopls v0.7.0
    golang.org/x/tools/gopls@v0.7.0 h1:JQBHW81Gsyim6iDjUwGoPeSpXrSqwen3isPJLfDfaYU=

Editor: VSCode
Reproducing steps:

  1. Open /usr/local/go/src/runtime/panic.go in VSCode.
  2. Hover for _panic in following code.
    func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) {
  3. Hover for _panic in another line.
    var p _panic

What did you expect to see?

step 3 give the same output as step 2.

What did you see instead?

step 2 gives:

type _panic struct {
    argp      unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
    arg       interface{}    // argument to panic
    link      *_panic        // link to earlier panic
    pc        uintptr        // where to return to in runtime if this panic is bypassed
    sp        unsafe.Pointer // where to return to in runtime if this panic is bypassed
    recovered bool           // whether this panic is over
    aborted   bool           // the panic was aborted
    goexit    bool
}
A _panic holds information about an active panic.

A _panic value must only ever live on the stack.

The argp and link fields are stack pointers, but don't need special handling during stack growth: because they are pointer-typed and _panic values only live on the stack, regular stack pointer adjustment takes care of them.

step 3 gives:

type _panic struct{argp unsafe.Pointer; arg interface{}; link *_panic; pc uintptr; sp unsafe.Pointer; recovered bool; aborted bool; goexit bool}

Appendix

  1. Here is the relevant rpc trace log.

// step 2

[Trace - 02:51:14.391 AM] Sending request 'textDocument/hover - (27)'.
Params: {"textDocument":{"uri":"file:///usr/local/go/src/runtime/panic.go"},"position":{"line":870,"character":27}}

[Trace - 02:51:14.399 AM] Received response 'textDocument/hover - (27)' in 7ms.
Result: {"contents":{"kind":"markdown","value":"```go\ntype _panic struct {\n\targp      unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink\n\targ       interface{}    // argument to panic\n\tlink      *_panic        // link to earlier panic\n\tpc        uintptr        // where to return to in runtime if this panic is bypassed\n\tsp        unsafe.Pointer // where to return to in runtime if this panic is bypassed\n\trecovered bool           // whether this panic is over\n\taborted   bool           // the panic was aborted\n\tgoexit    bool\n}\n```\n\nA \\_panic holds information about an active panic\\.\n\nA \\_panic value must only ever live on the stack\\.\n\nThe argp and link fields are stack pointers, but don\\'t need special\nhandling during stack growth\\: because they are pointer\\-typed and\n\\_panic values only live on the stack, regular stack pointer\nadjustment takes care of them\\.\n"},"range":{"start":{"line":870,"character":24},"end":{"line":870,"character":30}}}

// step 3

[Trace - 02:52:02.504 AM] Sending request 'textDocument/hover - (29)'.
Params: {"textDocument":{"uri":"file:///usr/local/go/src/runtime/panic.go"},"position":{"line":915,"character":10}}


[Trace - 02:52:02.511 AM] Received response 'textDocument/hover - (29)' in 7ms.
Result: {"contents":{"kind":"markdown","value":"```go\ntype _panic struct{argp unsafe.Pointer; arg interface{}; link *_panic; pc uintptr; sp unsafe.Pointer; recovered bool; aborted bool; goexit bool}\n```"},"range":{"start":{"line":915,"character":7},"end":{"line":915,"character":13}}}
  1. I tried to dig into the difference and found function HoverIdentifier returned different HoverInformation.
    But the source hasn't been changed for a long time. Is it feature or I need some extra options for gopls?

https://github.com/golang/tools/blob/55cd4804dfa0984a27cd61589b7f56f937e05545/internal/lsp/source/hover.go#L66-L71

func Hover(ctx context.Context, snapshot Snapshot, fh FileHandle, position protocol.Position) (*protocol.Hover, error) {
	ident, err := Identifier(ctx, snapshot, fh, position)Rohan Challa, 1 year ago: • internal/lsp: support textDocument/hover forif err != nil {
		return nil, nil
	}
	h, err := HoverIdentifier(ctx, ident)

// step 2

>>> p *h
$1 = {
  Signature = "type _panic struct {\n\targp      unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink\n\targ       interface{}    // argument to panic\n\tlink      *_pan"...,
  SingleLine = "type _panic struct{argp unsafe.Pointer; arg interface{}; link *_panic; pc uintptr; sp unsafe.Pointer; recovered bool; aborted bool; goexit bool}",
  Synopsis = "A _panic holds information about an active panic.",
  FullDocumentation = "A _panic holds information about an active panic.\n\nA _panic value must only ever live on the stack.\n\nThe argp and link fields are stack pointers, but don't need special\nhandling during stack growth: b"...,
  LinkPath = "",
  LinkAnchor = "",
  importPath = "",
  symbolName = "",
  source = {
    _type = 0xd6cc40,
    data = 0xc011e614a0
  },
  comment = 0xc00534ed20,
  typeName = "_panic",
  isTypeAlias = false
}

// step3

>>> p *h
$2 = {
  Signature = "type _panic struct{argp unsafe.Pointer; arg interface{}; link *_panic; pc uintptr; sp unsafe.Pointer; recovered bool; aborted bool; goexit bool}",
  SingleLine = "type _panic struct{argp unsafe.Pointer; arg interface{}; link *_panic; pc uintptr; sp unsafe.Pointer; recovered bool; aborted bool; goexit bool}",
  Synopsis = "",
  FullDocumentation = "",
  LinkPath = "",
  LinkAnchor = "",
  importPath = "",
  symbolName = "",
  source = {
    _type = 0xe23c00,
    data = 0xc0034e2f50
  },
  comment = 0x0,
  typeName = "",
  isTypeAlias = false
}
@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Jul 8, 2021
@gopherbot gopherbot added this to the Unreleased milestone Jul 8, 2021
@findleyr
Copy link
Contributor

findleyr commented Jul 9, 2021

Thank you for the repro.

I believe this is the same as #46158, but I am investigating.

@findleyr findleyr added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 9, 2021
@findleyr findleyr modified the milestones: Unreleased, gopls/v0.7.1 Jul 9, 2021
@findleyr findleyr self-assigned this Jul 9, 2021
@stamblerre stamblerre modified the milestones: gopls/v0.7.1, gopls/v0.7.2 Jul 26, 2021
@stamblerre stamblerre modified the milestones: gopls/v0.7.2, gopls/on-deck Sep 9, 2021
@stamblerre
Copy link
Contributor

Duplicate of #46158

@stamblerre stamblerre marked this as a duplicate of #46158 Sep 10, 2021
@katsusan
Copy link
Author

katsusan commented Sep 21, 2021

Hi @findleyr, thank you for the fix, it seems there is still an edge case not covered.

Another reproduce:

version:

D:\Projects\leetcode>gopls version
golang.org/x/tools/gopls v0.7.2
    golang.org/x/tools/gopls@v0.7.2 h1:kRKKdvA8GOzra8rhSFDClOR7hV/x8v0J0Vm4C/gWq8s=

D:\Projects\leetcode>go version
go version go1.17 windows/amd64

steps:

  1. open $GOROOT/src/runtime/proc.go.
  2. hover for the global variable debug in following code.

    go/src/runtime/proc.go

    Lines 199 to 202 in 6097ebe

    if debug.inittrace != 0 {
    inittrace.id = getg().goid
    inittrace.active = true
    }

hover result:
image

@stamblerre stamblerre reopened this Sep 21, 2021
@findleyr
Copy link
Contributor

Thanks very much for the repro.

@findleyr
Copy link
Contributor

Just looked into this. The debug struct is a real edge case: it is a var with a large struct literal type. For vars we use types.ObjectString to format their signature, which usually looks reasonable but in this case produces a very large type expression. It's hard to imagine doing something else: if we naively used the declaration syntax we'd have to handle all sorts of edge cases, like x := 2 // no type or x := []byte{/* lots of data */}, etc.

So I think the original issue is fixed, and we are unlikely to spend engineering time addressing this particular edge case. Closing so that this issue doesn't stagnate.

@katsusan
Copy link
Author

Thank you Robert for the investigation, the edge case doesn't miss type information and gopls needs improvement in other more important aspects, so it doesn't deserve if needs too much time.

@findleyr findleyr closed this as not planned Won't fix, can't repro, duplicate, stale Jul 1, 2022
@golang golang locked and limited conversation to collaborators Jul 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

4 participants