Releases: golang/tools
gopls/v0.13.0
These are release notes are identical to that of [email protected]. Thanks to all who tested the prerelease!
go install golang.org/x/tools/[email protected]
This release fixes several bugs and mitigates a few performance regressions. It also somewhat reduces the latency and CPU cost of most operations, and includes a few small additional features.
Performance improvements
While [email protected] drastically reduced memory usage, several operations got around 50% slower due to additional I/O reading from the filesystem and time spent decoding indexes. This release optimizes those additional operations to (in most cases) achieve parity or better with the equivalent operation in [email protected]. Additionally, this release reduces total CPU while typing or performing common operations.
Faster code actions
This release includes a particularly large performance improvement in the evaluation of code actions (including formatting/goimports on save). In the past, there have been several reasons why this operation was expensive -- VS Code users may recognize the getting code actions from "Go"
pop-up. This release fundamentally changes the way code actions are evaluated so that almost all of the work is pre-computed. As a result, formatting and adding or removing imports on save should be much faster.
Analysis performance
A notable exception to CPU performance parity with [email protected] is running static analysis. In this case, the additional cost incurred by [email protected] was not a regression, but rather the cost of analyzing many more packages to enable "deep" static analysis (see "Improved static analysis" in the [email protected] release notes.
In smaller repositories, the cost of this additional analysis is negligible -- analysis does not run until you stop typing, and typically just re-evaluates the changed package. However, it was discovered that in large workspaces that import low-level packages with a very large API surface (such as a cloud provider SDK or proto library), certain quadratic factors involved with the encoding/decoding of analysis results can dominate the cost of analysis, and result in enormous resource consumption: overloading the CPU and exhausting all memory.
This release partially mitigates those quadratic factors, significantly reducing their cost and limiting concurrency so that they do not exhaust all resources. However, fully eliminating these factors will require additional work to fix their quadratic nature. Until that is done, analysis may continue to be costly on certain repos, especially if "staticcheck"
is enabled (because staticcheck does more deep analysis than the default set of analyzers).
In the meantime, a notification is added to make you aware when analysis is slow, and provide an update on the progress of indexing "deep" analysis results. Canceling this notification will cancel the ongoing analysis, but it will resume after the next change. If you don't want to see these notifications, you can set the new "analysisProgressReporting"
setting to "false"
.
.
New Features
Highlight deprecated symbols
Deprecated symbols and packages are now marked as such. To turn off this feature, disable the "deprecated"
analysis.
Stub methods to fix missing method errors
The "stubmethods"
refactoring is now available as a quick-fix for errors related to missing methods.
Improvements to function extraction
Function extraction now puts context.Context
parameters first in the resulting extracted function. See golang/go#60738 for details.
Improvements to the embeddirective analyzer
The embed directive analyzer now verifies the location of //go:embed
directives, and provides a quick-fix to add missing "embed"
imports.
Bug fixes
In addition to the performance fixes listed above, this release fixes a couple crashes. A full list of all issues fixed can be found in the gopls/v0.13.0 milestone.
To report a new problem, please file a new issue at https://go.dev/issues/new. Please don't tolerate bugs.
What's next
Though we will continue to treat performance as a high priority, we believe this release addresses most unresolved issues related to the scalability improvements of [email protected], with the notable exception mentioned above of allowing robust static analysis to scale to the largest repositories. If you continue to have performance problems, please file an issue.
Our next focus will be on reducing the complexity of setting up your workspace. As much as possible, gopls should "just work" when you open a Go file, independent of your configuration or which directories you have open.
Thank you to our contributors!
@adonovan @bcmills @cuishuang @cuonglm @dmitshur @hyangah @jba @lfolger @pjweinb @rsc @timothy-king @vikblom @vikstrous2
gopls/v0.13.0-pre.3
These are release notes for a prerelease version of gopls. v0.13.0 will be released soon, but please try the prerelease if you can!
go install golang.org/x/tools/[email protected]
This release fixes several bugs and mitigates a few performance regressions. It also somewhat reduces the latency and CPU cost of most operations, and includes a few small additional features.
Performance improvements
While [email protected] drastically reduced memory usage, several operations got around 50% slower due to additional I/O reading from the filesystem and time spent decoding indexes. This release optimizes those additional operations to (in most cases) achieve parity or better with the equivalent operation in [email protected]. Additionally, this release reduces total CPU while typing or performing common operations.
Faster code actions
This release includes a particularly large performance improvement in the evaluation of code actions (including formatting/goimports on save). In the past, there have been several reasons why this operation was expensive -- VS Code users may recognize the getting code actions from "Go"
pop-up. This release fundamentally changes the way code actions are evaluated so that almost all of the work is pre-computed. As a result, formatting and adding or removing imports on save should be much faster.
Analysis performance
A notable exception to CPU performance parity with [email protected] is running static analysis. In this case, the additional cost incurred by [email protected] was not a regression, but rather the cost of analyzing many more packages to enable "deep" static analysis (see "Improved static analysis" in the [email protected] release notes.
In smaller repositories, the cost of this additional analysis is negligible -- analysis does not run until you stop typing, and typically just re-evaluates the changed package. However, it was discovered that in large workspaces that import low-level packages with a very large API surface (such as a cloud provider SDK or proto library), certain quadratic factors involved with the encoding/decoding of analysis results can dominate the cost of analysis, and result in enormous resource consumption: overloading the CPU and exhausting all memory.
This release partially mitigates those quadratic factors, significantly reducing their cost and limiting concurrency so that they do not exhaust all resources. However, fully eliminating these factors will require additional work to fix their quadratic nature. Until that is done, analysis may continue to be costly on certain repos, especially if "staticcheck"
is enabled (because staticcheck does more deep analysis than the default set of analyzers).
In the meantime, a notification is added to make you aware when analysis is slow, and provide an update on the progress of indexing "deep" analysis results. Canceling this notification will cancel the ongoing analysis, but it will resume after the next change. If you don't want to see these notifications, you can set the new "analysisProgressReporting"
setting to "false"
.
.
New Features
Highlight deprecated symbols
Deprecated symbols and packages are now marked as such. To turn off this feature, disable the "deprecated"
analysis.
Stub methods to fix missing method errors
The "stubmethods"
refactoring is now available as a quick-fix for errors related to missing methods.
Improvements to function extraction
Function extraction now puts context.Context
parameters first in the resulting extracted function. See golang/go#60738 for details.
Improvements to the embeddirective analyzer
The embed directive analyzer now verifies the location of //go:embed
directives, and provides a quick-fix to add missing "embed"
imports.
Bug fixes
In addition to the performance fixes listed above, this release fixes a couple crashes. A full list of all issues fixed can be found in the gopls/v0.13.0 milestone.
To report a new problem, please file a new issue at https://go.dev/issues/new. Please don't tolerate bugs.
What's next
Though we will continue to treat performance as a high priority, we believe this release addresses most unresolved issues related to the scalability improvements of [email protected], with the notable exception mentioned of allowing robust static analysis to scale to the largest repositories. If you continue to have performance problems, please file an issue.
Our next focus will be on reducing the complexity of setting up your workspace. As much as possible, gopls should "just work" when you open a Go file, independent of your configuration or which directories you have open.
Thank you to our contributors!
@adonovan @bcmills @cuishuang @cuonglm @dmitshur @hyangah @jba @lfolger @pjweinb @rsc @timothy-king @vikblom @vikstrous2
gopls/v0.12.4
This is a follow up to [email protected] fixing a crash in the new analysis driver, in the presence of certain invalid packages (golang/go#60952).
For more details, see the gopls/v0.12.4 milestone.
To report a new problem, please file a new issue at https://go.dev/issues/new.
gopls/v0.12.3
This release fixes a couple rare but significant performance regressions introduced in the v0.12.0 release.
Bug fixes
- Poor analysis performance on certain repositories (golang/go#60621): the first time a repository is analyzed, the new analysis driver loads data for open packages and all their dependencies. In v0.12.0, the naive recursion caused certain operations related to type information to be executed once per edge, not node, in the import graph. In some repositories with unusually large type information (e.g. hashicorp/terraform-provider-aws), this exhausted all memory. We have rewritten the recursion to process package types at most once per node.
- Missing fields and methods in autocompletion results (golang/go#53992): due to a change in v0.12.0, it became more likely that autocompletion would exhaust its time budget before all fields or methods had been collected. This release guarantees that autocompletion includes these critical completion items.
A full list of all issues fixed can be found in the gopls/v0.12.3 milestone.
To report a new problem, please file a new issue at https://go.dev/issues/new.
gopls/v0.12.2
This is an alias for the gopls/v0.12.1 release, and the gopls command reports its version as v0.12.1.
(It was created in the v0.12.1 release process as a defensive measure during an incident that we are investigating.)
Update (findleyr@): the incident in question was a failure to install "gopls@latest" due to a cached 404 in the sumdb. Many LSP clients install gopls@latest, so we cut v0.12.2 as a stopgap measure to ensure that installing gopls@latest continued to work.
Installing [email protected] eventually worked, after ~30m.
gopls/v0.12.1
This release fixes a few regressions/crashes in the v0.12.0 release:
- Unimported completion should use fuzzy matching (golang/go#60545).
- Fix a crash when method has receiver type
comparable
(golang/go#60544). - Fix for documentHighlight on import paths (golang/go#60435 -- this was pre-existing).
- Clear vulncheck diagnostics when they are toggled off (golang/go#60574).
These are also summarized in the release milestone.
gopls/v0.12.0
This release contains a major rewrite of the way gopls computes and stores package information, with the goal of reducing memory usage and allowing gopls to scale to larger repositories. This change can also significantly reduce startup time when workspaces are reopened, as gopls now uses a file-based cache to persist data across sessions. With these optimizations, gopls is finally able to fully analyze dependencies using the golang.org/x/tools/go/analysis framework, resulting in improved accuracy for analysis diagnostics.
You can install this release with go install
:
go install golang.org/x/tools/[email protected]
Support changes
As gopls matures, we're trying to simplify its configuration so that gopls Just Works in more scenarios, and so that we have fewer configuration combinations to test. This means that we will be gradually deprecating settings that affect the core behavior of gopls.
Removed experimental configuration options
As announced in the v0.10.0 release notes, this release removes support for the experimentalWorkspaceModule
and experimentalWatchedFileDelay
settings. The experimentalPackageCacheKey
setting is also removed, as it is irrelevant in the new design.
The experimentalWorkspaceModule
setting in particular may still be in use by some users. This setting has been superseded by built-in support for multi-module workspaces in the go
command, via Go workspaces. To get the equivalent behavior in [email protected], please create a go.work
file in your workspace using all desired modules. To use all modules in your workspace, run:
go work use -r .
Dropped support for Go 1.13-1.15, deprecated support for Go 1.16-1.17
As announced in the v0.10.0 release notes, this release drops support for Go 1.13-1.15, and in fact does not build with these Go versions.
Additionally, [email protected]
will be the final sequence of versions supporting Go 1.16-1.17, and therefore displays a deprecation notice when used with these Go versions.
Supported operating systems
Given that our users are almost entirely on Linux, Windows, or Darwin, we are discussing narrowing our support to focus on those operating systems, in golang/go#59981.
Performance improvements
The banner feature of this release is an internal redesign that significantly improves the way gopls scales in larger codebases. Performance, particularly memory usage, has long been a pain point for our users.
Reduced memory usage
Previous releases of gopls held typed syntax trees for all packages, in memory, all the time. With this release, these large data structures are ephemeral: as soon as they are constructed, an index of information derived from them is saved persistently to a file-based cache, and the data structures are recycled. The index for each package includes the locations of declaring and referring identifiers; the set of exported declarations and their types; the method sets of each interface; and any diagnostics and facts (see below) produced during analysis. The index holds all the information needed to serve global-scope LSP queries such as “references”, “implementations”, and so on.
Moving package information to a file-based cache greatly reduces the amount of RAM gopls uses, by almost an order of magnitude in larger projects. The table below shows the reductions in steady-state memory usage for three open-source Go repositories.
Project | Packages | In-use bytes v0.11.0 | v0.12.0 | Change |
---|---|---|---|---|
gopls | 405 | 497MB | 232MB | -53% |
kubernetes | 3137 | 3090MB | 832MB | -73% |
google-cloud-go + submods | 7657 | 5039MB | 863MB | -83% |
Improved invalidation
Internally, gopls now resembles an incremental build system such as go build
, which recompiles only the packages that have changed due to edits since the last build. If neither the inputs nor the configuration have changed, gopls can reuse the result previously computed.
Nonetheless, a change to a low-level package may in principle affect a large number of other packages. In practice though, the effects of many common changes, such as adding a statement within a function body, are local. So, gopls computes symbol dependencies at a much finer grain than the import dependency graph so that it can safely avoid invalidating packages that cannot be affected by local changes to their dependencies.
Gopls also now employs a number of more modest optimizations that may be characterized as “do less”. For example, many operations previously requested type information that wasn’t needed in most cases, or requested parsed syntax trees when raw file content would do. We have reduced the demand for unnecessary but computationally expensive steps.
How well is gopls performing for you?
We expect this release to make gopls faster for all users, but it involves a lot of new machinery. We’d love to hear how well it works for you and how it affects performance in your workspace. Has it improved the way you work? Are there ways it could do better? Let us know by filling out our survey or reporting an issue.
The gopls stats
command provides some metrics that may be useful when filing issues to help us understand performance problems and bugs. Please review its output before sharing, or use the -anon
flag if you prefer not to share any fields that might identify you or the names of your files.
New features
Improved static analysis
This release includes a new driver for golang.org/x/tools/go/analysis static checkers (as used in go vet
) that supports “facts”. Facts are deductions made during analysis of one package that may be assumed during analysis of another package. When the printf format-string checker encounters a function MyPrintf
that delegates to fmt.Sprintf
, it records this information as a fact about MyPrintf. This fact enables argument checking for calls to MyPrintf too, so gopls will emit a diagnostic for any call to MyPrintf with arguments of the wrong type for the format string.
Here’s an example from gopls’ own code base. The Hashf
function, defined in package source
, is a wrapper around fmt.Sprintf
.
The code below illustrates a call to source.Hashf with a formatting mistake, which gopls reports:
Gopls’ support for analysis facts thus enables it to discover and report many more diagnostics about your code than in previous releases.
Other features
Quick fixes to help manage go.work files
Gopls now pr...
gopls/v0.12.0-pre.3
This third prerelease contains several bug fixes following the v0.12.0-pre.2 release, and again contains some additional performance improvements. If all goes well. we plan to promote this to v0.12.0 on Tue May 30.
You can install this prerelease with go install
:
go install golang.org/x/tools/[email protected]
To revert to the last stable release, run go install golang.org/x/tools/gopls@latest
(though given that this is a release candidate, if you need to do this please file an issue).
Changes since pre.2
The most significant bug fix (golang/go#60089) relates to the file-watching mechanism by which gopls requests file change notifications from the client editor. Previously, gopls would generate a large glob pattern that, in large workspaces, would cause VSCode to get stuck. Now, gopls generates many smaller patterns, which works well with VSCode but may cause other editors (e.g. coc.nvim) to slow down. So, the new behavior is enabled automatically based on the client type, though it can be controlled explicitly using the new subdirWatchPatterns
setting (golang/go#59635).
The file-based cache introduced in gopls v0.12 has been simplified in this pre-release, borrowing a number of ideas from the go command's module cache. It achieves atomic updates using more reliable and portable system calls. It uses a simpler directory structure, saving space. It avoids most metadata update operations in its LRU eviction. And it uses an additional memory-based caching layer to avoid disk access in most cache-hit cases.
Other highlights:
- a number of optimizations related to
go mod tidy
operation (golang/go#60089); - a limit on the module scan, which was causing slow startup in some cases (golang/go#56496);
- placeholders for the name and type of each argument in completion of calls to unimported packages (golang/go#60269);
- a race fixed in in reloading of package metadata for ad-hoc packages (golang/go#57209);
- a new
gopls stats -anon
flag that redacts fields potentially containing user information.
In this release, we also announce the end of gopls' support for versions go1.16 and go1.17 of the go command. (golang/go#60341)
How to report a problem
As always, you can report gopls problem by filing an issue. We are particularly interested in any regressions you observe since [email protected].
If you would prefer not to report an issue on the issue tracker, you can also reach out to us via email to [email protected] or [email protected].
gopls/v0.12.0-pre.2
This second prerelease contains many bug fixes following the v0.12.0-pre.1 release. It also contains some minor additional performance improvements. See the release milestone for more details.
The [email protected] release contains an internal redesign of gopls for improved scalability. This prerelease should use much less memory than v0.11.0. See the v0.12.0-pre.1 release notes for more information.
How to report a problem
As always, you can report gopls problem by filing an issue. We are particularly interested in any regressions you observe since [email protected].
If you would prefer not to report an issue on the issue tracker, you can also reach out to us via email to [email protected] or [email protected].
What's next?
We have a few more small bugfixes to get in before the final v0.12.0 release. We will likely cut a third (and hopefully final) prerelease next week.
gopls/v0.12.0-pre.1
This prerelease version of gopls contains a major rewrite of the way gopls computes and stores package information, with the goal of reducing memory usage and allowing gopls to scale to larger repositories. This change can also significantly reduce startup time the second time a workspace is opened, as gopls now uses a file-based cache to preserve derived package information across sessions. With these optimizations, gopls is finally able to fully analyze dependencies using the x/tools/go/analysis
framework, resulting in improved accuracy for analysis diagnostics.
We'd love help testing this large change! If you are interested, please see below for details on what to expect, and how to report problems.
What to expect
In general, [email protected] should behave similarly to [email protected], but use much less memory. Memory savings typically range from 50-90%, depending on the shape of your repository. Note that memory will peak higher during startup or large operations, but should ideally never go as high as with [email protected], and in-use memory should stabilize at a much lower number. To see details about current memory usage, start gopls with -debug=localhost:8080
and visit http://localhost:8080/memory.
As part of the rewrite, certain operations may have gotten slightly slower overall, whereas others may have gotten slightly faster (e.g. see our performance dashboard). No operation should become unusably slow.
However, it is possible that gopls' new execution model performs disproportionately worse on certain operating systems, file systems, or repositories. If you encounter this, please let us know. See below for details on how to report a problem.
Support changes
This version of gopls implements the support changes discussed in the v0.10.0 release notes. Notably, it does not support Go 1.13-1.15, and removes support for several experimental features.
How to report a problem
You can always report a gopls problem by filing an issue. We are particularly interested in any regressions you observe since [email protected].
If you would prefer not to report an issue on the issue tracker, you can also reach out to us via email to [email protected] or [email protected].
We are aware of a number of remaining issues or regressions with the new release, tracked in the v0.12.0 milestone.
What's next?
We will continue to polish this release, and fix known regressions. We may make additional small performance improvements but do not expect large changes. Nevertheless, since this release constitutes a fundamental change to the way gopls works, we will likely cut one or more additional prereleases before the final release.
Looking beyond the v0.12.0 release, the recent redesign work paves the way for our next effort to make gopls self-configuring in more scenarios. With the previous design this would have been prohibitively expensive in memory, but soon gopls should just Do The Right Thing when you open any Go file on your machine.