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: missing error diagnostics for "missing function body" #64089

Closed
myitcv opened this issue Nov 13, 2023 · 5 comments
Closed

x/tools/gopls: missing error diagnostics for "missing function body" #64089

myitcv opened this issue Nov 13, 2023 · 5 comments
Labels
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

@myitcv
Copy link
Member

myitcv commented Nov 13, 2023

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

$ go version
go version go1.21.3 linux/arm64
$ go list -m golang.org/x/tools
golang.org/x/tools v0.15.1-0.20231110221557-aafa2e00a0d7
$ go list -m golang.org/x/tools/gopls
golang.org/x/tools/gopls v0.15.1-0.20231110221557-aafa2e00a0d7

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
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/home/myitcv/.cache/go-build'
GOENV='/home/myitcv/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/myitcv/gostuff/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/myitcv/gostuff'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/myitcv/gos'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/myitcv/gos/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.21.3'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
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 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4285289239=/tmp/go-build -gno-record-gcc-switches'

What did you do?

-- main.go --
package main

func main() {
	println("test")
}

func hello()

Open main.go in a gopls-powered editor.

What did you expect to see?

An error diagnostic telling me that func hello() is missing a function body. Just like that reported by go run:

$ go run main.go
# command-line-arguments
./main.go:7:6: missing function body

What did you see instead?

No error diagnostic.


cc @findleyr

@myitcv myitcv added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. gopls Issues related to the Go language server, gopls. labels Nov 13, 2023
@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label Nov 13, 2023
@gopherbot gopherbot added this to the Unreleased milestone Nov 13, 2023
@myitcv myitcv changed the title x/tools/gopls: x/tools/gopls: missing error diagnostics for "missing function body" Nov 13, 2023
@findleyr
Copy link
Contributor

The current behavior is correct (or rather, it's the best we can do). Per the spec, function bodies are optional in go code. The way I think of it is: it's not an error until you try to link, and with go:linkname directives (or other linker interventions) we can't know whether or not that function will be linked correctly.

Put differently, if we did this there would be thousands of errors in the Go standard library, and IIUC we have no practical way of identifying which missing function bodies are missing by accident.

By contrast, generic functions and init functions do require a function body, and gopls correctly reports an error in these cases.

@suzmue suzmue modified the milestones: Unreleased, gopls/backlog Nov 13, 2023
@findleyr
Copy link
Contributor

Closing as I don't think we can do anything here. Please correct me if I'm wrong.

@myitcv
Copy link
Member Author

myitcv commented Nov 14, 2023

The current behavior is correct

For some definition of "correct" 😄

From the perspective of someone writing a Go program using gopls, it is not correct if my goal is to have all errors surfaced in my editor. Because the reality is that I cannot otherwise say "I am done with all the errors in my editor, let me now run my program". Perhaps a good analogy here is the go:embed directives: if errors related to these directives were not surfaced by gopls, then I feel we would be having the same discussion. But they are so we are not, and from my perspective as a user of gopls that is "correct". Just as link errors not being surfaced are not present, hence this issue.

However, this again comes back to the point of "what am I trying to do with gopls in this instance". In the case of this issue, I'm trying to get to a state where I can run the main program. I realise that we don't have a mechanism of support the description of such intentions, but again I wouldn't call this "correct".

So whilst it might internally be "correct" to not report errors in this situation, I'm not sure I agree that it is "correct" from the perspective of a gopls user, where the raison d'être of gopls is to help me fix my code.

@findleyr
Copy link
Contributor

The current behavior is correct (or rather, it's the best we can do)

You removed the parenthetical :)! It is "correct" according to the spec, and unfortunate that it's the best we can do.

Absent external configuration (such as a build definition), and a lot of additional logic, I don't think there's a way to address this problem. I'd be happy to hear otherwise.

@adonovan
Copy link
Member

adonovan commented Nov 14, 2023

Gopls, by design, executes only modular (package-at-a-time) analyses in real time, analogous to a compiler. By contrast, whole program analyses such as the linker or govulncheck aren't executed in real time because they need additional external information--such as which main package(s) to operate on---which means their diagnostics are not a function of a package and its transitive closure. As you can imagine, this makes them prohibitively expensive to compute in real time. You can of course request whole-program analyses explicitly, for example by invoking a "run test" code action on Test function, or invoking govulnheck from your go.mod file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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

5 participants