| --- |
| title: "Gopls release v0.21.0 (Dec 2025)" |
| --- |
| |
| ## Configuration changes |
| |
| - The new `newGoFileHeader` option allows toggling automatic insertion of the copyright comment |
| and package declaration in a newly created Go file. |
| |
| - The default value of the `codelenses` setting now includes |
| `run_govulncheck: true`, causing gopls to offer a "Run govulncheck" |
| command associated with the `module` declaration in a go.mod file. |
| |
| - The experimental `vulncheck` setting now supports the enum value |
| `"Prompt"`, meaning that vulncheck can be triggered via a prompt; |
| this is now the default. |
| |
| - The new, experimental `renameMovesSubpackages` setting determines |
| whether a rename package operation applies to subdirectories; see |
| below for details. |
| |
| ## Navigational features: |
| |
| Hover can now report information about selected subexpressions (#69058). |
| For example, selecting the region indicated below: |
| |
| x[i].f() |
| ~~~~ |
| |
| will report information about the subexpression `x[i]`, such as its |
| type, constant value (if appropriate), and methods. |
| Previously, Hover would report only about `x`, `i`, or `f`. |
| |
| This feature requires the client to supply an extra field in the |
| `textDocumentPositionParams` part of its LSP `textDocument/hover` |
| request: the standard struct has a single `position` of type |
| `Position`, but gopls can also handle a `range` field of type |
| `Range` that specifies the extent of the text selection. |
| (If supplied, it must enclose the `position`.) |
| |
| The VS Code code extension already populates this field. We plan to |
| use it across various requests, and to lobby for its adoption by the |
| LSP standard. |
| |
| Other features in brief: |
| |
| - Definition now works for fields in doc links in comments (#75038). |
| - Hover adds navigation to doc links in hovers (golang/vscode-go#3827). |
| - Hover now reports information (size, etc) about embedded fields, not just their types (#75975). |
| - Folding Range now displays closing parens (#75229) and more ranges (#73735). |
| |
| ## Analysis features |
| |
| ### `reflecttypefor` analyzer |
| |
| <!-- golang/go#60088 --> |
| |
| The new `reflecttypefor` analyzer modernizes calls to `reflect.TypeOf` |
| to use `reflect.TypeFor` when the runtime type is known at compile |
| time. For example: |
| |
| reflect.TypeOf(uint32(0)) |
| |
| becomes: |
| |
| reflect.TypeFor[uint32]() |
| |
| ### `newexpr` analyzer |
| |
| <!-- golang/go#45624 --> |
| |
| The `newexpr` analyzer finds declarations of and calls to functions |
| of this form: |
| ```go |
| func varOf(x int) *int { return &x } |
| |
| use(varOf(123)) |
| ``` |
| modernizing them when appropriate to use the `new(expr)` feature of Go 1.26: |
| ```go |
| //go:fix inline |
| func varOf(x int) *int { return new(x) } |
| |
| use(new(123)) |
| ``` |
| |
| Such wrapper functions are widely used in serialization packages, |
| for instance the proto.{Int64,String,Bool} helpers used with |
| protobufs. |
| |
| ### `stditerators` analyzer |
| |
| <!-- golang/go#75693 --> |
| |
| The `stditerators` analyzer replaces loops of this form, |
| |
| for i := 0; i < x.Len(); i++ { |
| use(x.At(i)) |
| } |
| |
| or their "range x.Len()" equivalent, by |
| |
| for elem := range x.All() { |
| use(elem) |
| } |
| |
| for various types in the standard library that now offer a |
| modern iterator-based API. |
| |
| ### `stringscut` analyzer |
| |
| <!-- golang/go#71369 --> |
| |
| The `stringscut` analyzer modernizes various patterns of use of |
| `strings.Index` such as: |
| |
| i := strings.Index(s, sep) |
| if i >= 0 { |
| use(s[i:]) |
| } |
| |
| by a call to `strings.Cut`, introduced in Go 1.25: |
| |
| before, after, ok := strings.Cut(s, sep) |
| if ok { |
| use(after) |
| } |
| |
| ### `plusbuild` analyzer |
| |
| <!-- golang/go#73605 --> |
| |
| The `plusbuild` analyzer removes old-style `+build` build-tag comments |
| when they are redundant with the newer form: |
| |
| //go:build linux |
| // +build linux |
| |
| ### `errorsastype` analyzer |
| |
| <!-- golang/go#75692 --> |
| |
| The `errorsastype` analyzer replaces calls to `errors.As`: |
| |
| var myErr *MyError |
| if errors.As(err, &myErr) { ... } |
| |
| by the more modern `errors.AsType`, when the type is known statically: |
| |
| if myErr, ok := errors.AsType[*MyError](err) { ... } |
| |
| |
| ### `unsafefuncs` analyzer |
| |
| <!-- golang/go#76648 --> |
| |
| The `unsafefuncs` analyzer replaces arithmetic such as: |
| |
| unsafe.Pointer(uintptr(ptr) + uintptr(n)) |
| |
| where ptr is an unsafe.Pointer, by calls to `unsafe.Add`, added in Go 1.17. |
| |
| unsafe.Add(ptr, n) |
| |
| ### Miscellaneous |
| |
| - The `minmax` modernizer now removes user-defined min/max functions when they are redundant. |
| - The `stringscutprefix` modernizer now handles `strings.CutSuffix` too. <!-- #75205 --> |
| - The `yield` and `nilness` analyzers handle control-flow booleans more precisely. <!-- #74136, #75924 --> |
| - The `printf` analyzer now checks calls to local anonymous printf-wrapper functions too. |
| - The `staticcheck` suite has been updated to v0.7. |
| |
| ## Code transformation features |
| |
| ### Generalized package renaming |
| |
| <!-- #57171 #75812 --> |
| |
| The Rename operation, invoked on a `package p` declaration, now |
| prompts you to edit the entire package path. This allows you to choose |
| not just a new name for the package, but a new directory anywhere |
| within the same module. For example, you can rename `example.com/foo` |
| to `example.com/internal/bar`, and the tool will move files and update |
| imports as needed. |
| |
| By default, subpackages are no longer moved with the renamed package. |
| Enable the new (experimental) `renameMovesSubpackages` setting if you |
| want subpackages to move too. (In due course, we will add LSP support |
| for dialogs so that the server can query the user's intent |
| interactively.) |
| |
| This feature requires client support for the LSP |
| [`textDocument/prepareRename`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareRename) operation. |
| |
| ### Renaming from a doc link |
| |
| <!-- golang/go#42301 --> |
| The Rename operation now treats [doc links](https://tip.golang.org/doc/comment#doclinks) |
| like identifiers, so you can initiate a renaming from a doc link. |
| |
| ## Model context protocol (MCP) features |
| |
| The MCP server now supports the `go_rename_symbol` tool, which permits |
| an agent to rename a symbol based on its name (e.g. `fmt.Println` or |
| `bytes.Buffer.WriteString`). The tool uses the symbol index to resolve |
| the name to a declaration and then initiates a renaming. |
| |
| The server also supports the `gopls.vulncheck` tool, allowing agents |
| to scan packages for security vulnerabilities. |
| |
| ## Closed issues |
| |
| https://github.com/golang/go/milestone/399?closed=1 |
| |