The case of the old gopls

,

I recently started a new Go project and the language server would not work in Helix. It worked fine in other projects. I tried everything – removing modules one by one, etc. I then fired up VS Code and it did not work there. I eventually noticed an error popping up momentarily that that gopls needed re-complied for Go 1.23. It turns out I had installed gopls using go get/install some time ago:

go install golang.org/x/tools/gopls@latest

While this is very handy, it tends to never get updated unless you have problems.

Arch packages gopls, so it was a simple matter to install the Arch packaged version and everything works fine. Now I’ll always be running the latest version of Go and gopls, and they should match.

The go.mod file specifies the Go version. In the case of my older projects, they contained go 1.20 whereas the new project contained go 1.23. So that is why gopls worked with the older projects and not newer – the different version specified in go.mod.

I did some digging into what the Go compiler does with the go version in go.mod:

When you have Go 1.23 installed on your system but your go.mod file specifies Go 1.20, the newer compiler (1.23) supports the older version (1.20) through a feature called “toolchain management.” This feature ensures backward compatibility and allows developers to work with projects using different Go versions.

Here’s how it works:

Toolchain Management

The Go compiler uses the version specified in the go.mod file to determine which language features and behaviors to enable or restrict. This means:

  1. The compiler will limit itself to the features and behaviors available in Go 1.20, even though it’s capable of more recent features 4.
  2. It will maintain compatibility with the syntax, standard library functions, and language semantics of Go 1.20 4.

Backward Compatibility

Go’s strong commitment to backward compatibility plays a crucial role in this process:

  • The Go 1 compatibility promise ensures that code written for earlier versions of Go 1.x will continue to compile and run correctly on newer versions 2.
  • This allows developers to use the latest Go compiler while still working on projects that target older Go versions 2.