Gopls: Diagnostics

Gopls continuously annotates all your open files of source code with a variety of diagnostics. Every time you edit a file or make a configuration change, gopls asynchronously recomputes these diagnostics and sends them to the client using the LSP publishDiagnostics notification, giving you real-time feedback that reduces the cost of common mistakes.

Diagnostics come from two main sources: compilation errors and analysis findings.

  • Compilation errors are those that you would obtain from running go build. Gopls doesn't actually run the compiler; that would be too slow. Instead it runs go list (when needed) to compute the metadata of the compilation, then processes those packages in a similar manner to the compiler front-end: reading, scanning, and parsing the source files, then type-checking them. Each of these steps can produce errors that gopls will surface as a diagnostic.

    The source field of the LSP Diagnostic record indicates where the diagnostic came from: those with source "go list" come from the go list command, and those with source "compiler" come from gopls' parsing or type checking phases, which are similar to those used in the Go compiler.

    A diagnostic due to a type error

    The example above shows a string + int addition, causes the type checker to report a MismatchedTypes error. The diagnostic contains a link to the documentation about this class of type error.

  • Analysis findings come from the Go analysis framework, the system used by go vet to apply a variety of additional static checks to your Go code. The best-known example is the printf analyzer, which reports calls to fmt.Printf where the format “verb” doesn't match the argument, such as fmt.Printf("%d", "three").

    Gopls provides dozens of analyzers aggregated from a variety of suites. See Analyzers for the complete list. The source field of each diagnostic produced by an analyzer records the name of the analyzer that produced it.

    A diagnostic due to an analysis finding

    The example above shows a printf formatting mistake. The diagnostic contains a link to the documentation for the printf analyzer.

Recomputation of diagnostics

Diagnostics are automatically recomputed each time the source files are edited.

Compilation errors in open files are updated after a very short delay (tens of milliseconds) after each file change, potentially after every keystroke. This ensures rapid feedback of syntax and type errors while editing.

Compilation and analysis diagnostics for the whole workspace are much more expensive to compute, so they are usually recomputed after a short idle period (around 1s) following an edit.

The diagnosticsDelay setting determines this period. Alternatively, diagnostics may be triggered only after an edited file is saved, using the diagnosticsTrigger setting.

Gopls does not currently support “pull-based” diagnostics, which are computed synchronously when requested by the client; see golang/go#53275.

Quick fixes

Each analyzer diagnostic may suggest one or more alternative ways to fix the problem by editing the code. For example, when a return statement has too few operands, the fillreturns analyzer suggests a fix that heuristically fills in the missing ones with suitable values. Applying the fix eliminates the compilation error.

An analyzer diagnostic with two alternative fixes

The screenshot above shows VS Code's Quick Fix menu for an “unused parameter” analysis diagnostic with two alternative fixes. (See Remove unused parameter for more detail.)

Suggested fixes that are indisputably safe are code actions whose kind is "source.fixAll". Many client editors have a shortcut to apply all such fixes.

TODO(adonovan): audit all the analyzers to ensure that their documentation is up-to-date w.r.t. any fixes they suggest.

Settings:

  • The diagnosticsDelay setting determines the idle period after an edit before diagnostics are recomputed.
  • The diagnosticsTriggerr setting determines what events cause recomputation of diagnostics.
  • The linkTarget setting specifies the base URI for Go package links in the Diagnostic.CodeDescription field.

Client support:

  • VS Code: Diagnostics appear as a squiggly underline. Hovering reveals the details, along with any suggested fixes.
  • Emacs + eglot: Diagnostics appear as a squiggly underline. Hovering reveals the details. Use M-x eglot-code-action-quickfix to apply available fixes; it will prompt if there are more than one.
  • Vim + coc.nvim: ??
  • CLI: gopls check file.go