---
title: "Gopls release v0.18.0 (Feb 2025)"
---

## Configuration Changes

<!-- TODO(rfindley): add links to relevant settings documentation -->

- The experimental `Structured` value for the `hoverKind` option is no longer
  supported.

- The `gc_details` code lens has been deleted. (It was previously disabled by
  default.) This functionality is now available through the
  `toggleCompilerOptDetails` code action (documented below), as code
  actions are better supported than code lenses across a range of clients.

  VS Code's special "Go: Toggle GC details" command continues to work.

- The experimental `semanticTokenTypes` and `semanticTokenModifiers` options
  allow selectively disabling certain types of tokens or token modifiers in
  `textDocument/semanticTokens` responses.

  These options supersede the `noSemanticString` and `noSemanticTokenNumber`
  options, which are now deprecated. Users can instead set
  `"semanticTokenTypes": {"string": false, "number": false}` to achieve the
  same result. For now, gopls still honors `noSemanticTokenString` and
  `noSemanticToken`, but will stop supporting them in a future release.

- The new `workspaceFiles` option allows configuring glob patterns matching
  files that define the logical build of the workspace. This option is only
  needed in environments that use a custom golang.org/x/tools/go/packages
  driver.

## New features

### "{Show,Hide} compiler optimization details" code action

This code action, accessible through the "Source Action" menu in VS
Code, toggles a per-directory flag that causes Go compiler optimization
details to be reported as diagnostics. For example, it indicates which
variables escape to the heap, and which array accesses require bounds
checks.

TODO: add links to the complete manual for each item.

### New `modernize` analyzer

Gopls now reports when code could be simplified or clarified by
using more modern features of Go, and provides a quick fix to apply
the change.

For example, a conditional assignment using an if/else statement may
be replaced by a call to the `min` or `max` built-in functions added
in Go 1.18.

Use this command to apply modernization fixes en masse:
```
$ go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./...
```

### New `unusedfunc` analyzer

Gopls now reports unused functions and methods, giving you near
real-time feedback about dead code that may be safely deleted.
Because the analysis is local to each package, only unexported
functions and methods are candidates.
(For a more precise analysis that may report unused exported
functions too, use the `golang.org/x/tools/cmd/deadcode` command.)

### New `hostport` analyzer

With the growing use of IPv6, forming a "host:port" string using
`fmt.Sprintf("%s:%d")` is no longer appropriate because host names may
contain colons. Gopls now reports places where a string constructed in
this fashion (or with `%s` for the port) is passed to `net.Dial` or a
related function, and offers a fix to use `net.JoinHostPort`
instead.

### Other analyzer changes

- The `unusedvariable` quickfix is now on by default.
- The `unusedparams` analyzer no longer reports finding for generated files.

### New `gofix` analyzer

Gopls now reports when a function call or a use of a constant should be inlined.
These diagnostics and the associated code actions are triggered by "//go:fix inline"
directives at the function and constant definitions.
(See [the go:fix proposal](https://go.dev/issue/32816).)

For example, consider a package `intmath` with a function `Square(int) int`.
Later the more general `Pow(int, int) int` is introduced, and `Square` is deprecated
in favor of calling `Pow` with a second argument of 2. The author of `intmath`
can write this:
```
//go:fix inline
func Square(x int) int { return Pow(x, 2) }
```
If gopls sees a call to `intmath.Square` in your code, it will suggest inlining
it, and will offer a code action to do so.

The same feature works for constants.
With a constant definition like this:
```
//go:fix inline
const Ptr = Pointer
```
gopls will suggest replacing `Ptr` in your code with `Pointer`.

Use this command to apply such fixes en masse:

```
$ go run golang.org/x/tools/go/analysis/passes/inline/cmd/inline@latest -fix ./...
```

### "Implementations" supports generics

At long last, the "Go to Implementations" feature now fully supports
generic types and functions (#59224).

For example, invoking the feature on the interface method `Stack.Push`
below will report the concrete method `C[T].Push`, and vice versa.

```go
package p

type Stack[T any] interface {
	Push(T) error
	Pop() (T, bool)
}

type C[T any] struct{}

func (C[T]) Push(t T) error { ... }
func (C[T]) Pop() (T, bool) { ... }

var _ Stack[int] = C[int]{}
```

### Extract all occurrences of the same expression under selection

When you have multiple instances of the same expression in a function,
you can use this code action to extract it into a variable.
All occurrences of the expression will be replaced with a reference to the new variable.

### Improvements to "Definition"

The Definition query now supports additional locations:

- When invoked on a return statement, it reports the location
  of the function's result variables.
- When invoked on a break, goto, or continue statement, it reports
  the location of the label, the closing brace of the relevant
  block statement, or the start of the relevant loop, respectively.

### Improvements to "Hover"

When invoked on a return statement, hover reports the types of
the function's result variables.

### UX improvements to format strings

#### "DocumentHighlight"

When your cursor is inside a printf-like function, gopls now highlights the relationship between
formatting verbs and arguments as visual cues to differentiate how operands are used in the format string.

```go
fmt.Printf("Hello %s, you scored %d", name, score)
```

If the cursor is either on `%s` or `name`, gopls will highlight `%s` as a write operation,
and `name` as a read operation.

#### "SemanticHighlight"

Similar to the improvements to DocumentHighlight, gopls also reports formatting verbs
as "format" modifier for token type "string" to better distinguish them with other parts of the format string.

```go
fmt.Printf("Hello %s, you scored %d", name, score)
```

`%s` and `%d` will have token type "string" and modifier "format".
