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: definition request fails on method with receiver type of form C.T (cgo) #59723

Closed
ahamza360 opened this issue Apr 20, 2023 · 2 comments
Assignees
Labels
Documentation 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

@ahamza360
Copy link

gopls version

Build info

golang.org/x/tools/gopls v0.11.0
golang.org/x/tools/gopls@v0.11.0 h1:/nvKHdTtePQmrv9XN3gIUN9MOdUrKzO/dcqgbG6x8EY=
github.com/BurntSushi/toml@v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/google/go-cmp@v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
golang.org/x/exp@v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE=
golang.org/x/exp/typeparams@v0.0.0-20221031165847-c99f073a8326 h1:fl8k2zg28yA23264d82M4dp+YlJ3ngDcpuB1bewkQi4=
golang.org/x/mod@v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
golang.org/x/sync@v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys@v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/text@v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/tools@v0.3.1-0.20221213193459-ca17b2c27ca8 h1:7/HkGkN/2ktghBCSRRgp31wAww4syfsW52tj7yirjWk=
golang.org/x/vuln@v0.0.0-20221109205719-3af8368ee4fe h1:qptQiQwEpETwDiz85LKtChqif9xhVkAm8Nhxs0xnTww=
honnef.co/go/tools@v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
mvdan.cc/gofumpt@v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=
mvdan.cc/xurls/v2@v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=
go: go1.20.3

go env

GO111MODULE="auto"
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/hamza/Library/Caches/go-build"
GOENV="/Users/hamza/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/hamza/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/hamza/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.20.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/hamza/workspace/Go/test2/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/2q/n7_883yd56v1jnstwt643pw00000gn/T/go-build263698593=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I have 2 similar versions of the same program. Both work as expected while running the code from terminal. However, version 2 gives the error in vscode even though it still compiles.

Version 1:

package main

/*
#include <stdlib.h>

typedef struct Person {
    char* name;
    int age;
} Person;
*/
import "C"
import (
	"fmt"
	"unsafe"
)

type Person C.Person

func (p Person) PrintName() {
	name := C.GoString(p.name)
	fmt.Println(name)
}

func main() {
	name := C.CString("John")
	defer C.free(unsafe.Pointer(name))

	age := C.int(30)

	cPerson := C.Person{
		name: name,
		age:  age,
	}

	person := Person(cPerson)
	person.PrintName()
}

Version 2:

package main

/*
#include <stdlib.h>

typedef struct Person {
    char* name;
    int age;
} Person;
*/
import "C"
import (
	"fmt"
	"unsafe"
)

func (p *C.Person) PrintName() {
	name := C.GoString(p.name)
	fmt.Println(name)
}

func main() {
	name := C.CString("John")
	defer C.free(unsafe.Pointer(name))

	age := C.int(30)

	cPerson := C.Person{
		name: name,
		age:  age,
	}

	person := C.Person(cPerson)
	person.PrintName()
}

What did you expect to see?

Version 2 of the code should have worked the same way as version 1 in VSCode

What did you see instead?

For version 2, at person.PrintName() it shows

person.PrintName undefined (type _Ctype_struct_Person has no field or method PrintName)compilerMissingFieldOrMethod

image

Moreover, when PrintName is clicked, it doesn't take to the function.

This is a simplified example of the issue that we are facing in our code base which is not very easy to refactor.

Editor and settings

VS Code Settings:

"go.lintTool": "golangci-lint",
  "go.lintFlags": ["--fast"],
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "go.toolsManagement.autoUpdate": true,
  "go.gopath": "",
  "go.lintOnSave": "file",
  "go.gocodeAutoBuild": true,
  "go.useLanguageServer": true,
  "go.buildOnSave": true,
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }

Logs

[Error - 02:20:39] Request textDocument/definition failed. Message: no object found for ident PrintName Code: 0

@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 Apr 20, 2023
@gopherbot gopherbot added this to the Unreleased milestone Apr 20, 2023
@suzmue suzmue added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 20, 2023
@suzmue suzmue modified the milestones: Unreleased, gopls/later Apr 20, 2023
@adonovan
Copy link
Member

adonovan commented Apr 20, 2023

Thanks for the very clear bug report. I confirm the error in program 2 (but not 1) using VSCode and gopls@v0.11.0 and gopls@master.

The fundamental problem is that it probably shouldn't be legal to declare a method whose receiver is *C.T since ostensibly that's a type from another package. The Go compiler allows it, because the current implementation of cgo does a source transformation step that replaces C.T with a generated type in the current package, something like __C__T_mumble. But really the tool should disallow it. By constrast, gopls is based on the go/types package, which doesn't do a source transformation and interprets the C.T reference directly. It therefore complains about the method declaration.

I argue that go/types is correct and the go command (cgo) has a bug, but that question hasn't been resolved yet. See
#57926

In any case, we have the unfortunate situation of code (like both of your example programs) existing in the wild that depends on the buggy behavior. It is probably not straightforward for us to change go/types to match the compiler behavior (nor desirable, if we all agree it's a bug).

If you have the power, I recommend that you delete any method declarations whose receiver type is of the form C.T.

@adonovan
Copy link
Member

Now that #57926 has been resolved by making the cgo tool reject attempts to declare methods on types of the form C.T, I'm going to close this. The error message could perhaps be improved, but I think this will become vanishingly rare in practice.

@adonovan adonovan changed the title x/tools/gopls: Request textDocument/definition failed. "no object found for ident ..." x/tools/gopls: definition request fails on method with receiver type of form C.T (cgo) May 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation 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