Skip to content

Releases: dominikh/go-tools

Staticcheck 2026.2rc1 (v0.8.0-rc.1)

Pre-release

Choose a tag to compare

@dominikh dominikh released this 25 Jun 17:57
2026.2rc1

This is a release candidate of Staticcheck 2026.2. It has been built with Go 1.27rc1 and supports analyzing Go 1.27 code.

Added support for Go 1.27

This release updates Staticcheck’s database of deprecated standard library APIs to cover Go 1.27. Furthermore, it adds support for two new language features: generic methods and struct initializers with direct references to embedded fields

Support for GOCACHEPROG

Staticcheck now supports the same GOCACHEPROG environment variable and protocol as the go tool. This allows users to provide their own implementation of the build/fact/diagnostic cache.

Case-insensitive check names

All places that accept names of checks, such as the -checks and -explain flags, ignore directives, and the checks setting in configuration files now ignore the case of the provided names. That is, SA1000, sa1000, and sA1000 all refer to the same check.

Performance improvements for some packages

We have made changes to better support code with very complex control flow graphs, such as the output of wasm2go. In one particularly pathological case, memory usage was reduced from 10 GiB to 1.5 GiB and wall time from 73 s to 13 s.

Checks

New checks

One new check has been added. SA9010 flags statements of the form defer foo() where foo returns a function. Usually, functions like that expect the user to defer calling the returned function.

For example:

// Start starts a thing. The returned function has to be called once the thing
// is no longer needed.
func Start() func() {
	// do some work here
	return func() {
		// undo some work here
	}
}

func user() {
	// This is doubly wrong! It won't call Start until this function returns,
	// and then it won't call the function returned by Start.
	defer Start()
	...
}

Changed checks

The following checks have been improved:

  • SA1019 now flags uses of deprecated fields in struct initializers. Additionally, it is more consistent in the way diagnostics are formatted.
  • SA1026 and SA9005 now check calls to MarshalIdent functions, too.
  • SA4003 now checks comparisons involving generics.
  • SA4006 has gained support for compound operators (+=, ^=, etc) as well as postfix increment and decrement.
  • SA4023 has been reimplemented. As a result, it may find new issues in existing code, but also miss issues it has found before.
  • SA5011 has been disabled due to internal changes. It is unclear whether it will be enabled again in the future. As an alternative, gopls contains the nilness analyzer, which has similar checks.
  • SA6005 emits a clearer diagnostic when the result of strings.EqualFold has to be inverted.
  • Documentation has been added to several checks (SA1002, SA1012, SA1014, SA1020, SA2000, SA2003, and SA4010)
  • S1005 no longer flags unnecessary assignments to the blank identifier for map indexing. This is to allow v, _ := m[k] as a hint that the key may be missing from the map but that using the zero value is fine.
  • U1000 has gained better support for the combined use of generics and interfaces. It should emit far fewer false positives now (issue 1616, issue 1440, issue 1294).
  • ST1001 includes the new simd/archsimd package in the default value of the dot_import_whitelist setting.

Staticcheck 2026.1 (v0.7.0)

Choose a tag to compare

@dominikh dominikh released this 13 Feb 19:08
2026.1

Improved Go 1.25 and Go 1.26 support

This release updates Staticcheck’s database of deprecated standard library APIs to cover the Go 1.25 and Go 1.26 releases, as well as to add some crypto/elliptic deprecations from Go 1.21 that were missing. Furthermore, it adds support for new(expr), which was added in Go 1.26.

Other changes

  • Version mismatch checks have been relaxed and no longer care about mismatches in the patch level. For example, Staticcheck built with Go 1.26.0 will be able to check code using Go 1.26.1.
  • Staticcheck no longer opens staticcheck.conf files that aren’t regular files (or symlinks to regular files). See this gomodfs issue for the motivation behind this change.
  • Staticcheck now exits with a non-zero status code if it encountered an invalid configuration file.

Checks

Changed checks

The following checks have been improved:

  • SA1026 no longer panics when checking code that tries to marshal named functions (issue 1660).
  • SA4000 no longer flags var _ = T{} == T{}, a pattern used to ensure that type T is comparable (issue 1670).
  • SA4000 now correctly skips structs containing floats.
  • SA4000 now skips functions from the math/rand/v2 package.
  • SA4003 now skips over generated files.
  • SA4030 now also checks uses of math/rand/v2.
  • SA5008 has been updated with better support for encoding/json/v2.
  • SA5010 no longer tries to reason about generics, to avoid false positives.
  • ST1019 no longer flags duplicate imports of unsafe, mainly to play nice with cgo.
  • ST1003 and QF1002 now emit more concise positions, benefitting users of gopls (issue 1647).
  • ST1019 now allows importing the same package twice, once using a blank import (issue 1688).
  • QF1008 no longer offers to delete all embedded fields from a selector expression. Even when two fields are individually superfluous, removing both might change the semantics of the code (issue 1682).
  • QF1012 now detects more uses of bytes.Buffer (issue 1097).
  • A bug in the intermediate representation was fixed, affecting the behavior of various checks (issue 1654).

Staticcheck 2025.1.1 (v0.6.1)

Choose a tag to compare

@dominikh dominikh released this 05 Mar 23:48
2025.1.1

This is a re-release of 2025.1 but with prebuilt binaries that have been built with Go 1.24.1.

Staticcheck 2025.1 (v0.6.0)

Choose a tag to compare

@dominikh dominikh released this 11 Feb 21:12
2025.1

Added Go 1.24 support

This release adds support for Go 1.24.

Checks

Changed checks

The following checks have been improved:

  • U1000 treats all fields in a struct as used if the struct has a field of type structs.HostLayout.
  • S1009 now emits a clearer message.
  • S1008 no longer recommends simplifying branches that contain comments (issue 704, issue 1488).
  • S1009 now flags another redundant nil check (issue 1605).
  • QF1002 now emits a valid automatic fix for switches that use initialization statements (issue 1613).

Staticcheck 2024.1.1 (v0.5.1)

Choose a tag to compare

@dominikh dominikh released this 14 Aug 20:38
2024.1.1

This release fixes the detection of the used Go version when Go was compiled with experimental features such as rangefunc or boringcrypto (#1586).

Staticcheck 2024.1 (v0.5.0)

Choose a tag to compare

@dominikh dominikh released this 13 Aug 17:35
2024.1

Backwards incompatible changes

Staticcheck 2024.1 contains the following backwards incompatible changes:

  • The keyify utility has been removed. The recommended alternative is gopls.
  • staticcheck -merge now exits with a non-zero status if any problems have been found.

Improved Go 1.22 support

This release updates Staticcheck’s database of deprecated standard library APIs to cover the Go 1.22 release. Furthermore, checks have been updated to correctly handle the new “for” loop variable scoping behavior as well as ranging over integers.

Added Go 1.23 support

Staticcheck 2024.1 has full support for iterators / range-over-func. Furthermore, SA1015 will skip any code targeting Go 1.23 or newer, as it is now possible to use time.Tick without leaking memory.

Improved handling of Go versions

Go 1.21 more rigorously defined the meaning of the go directive in go.mod files, as well as its interactions with //go:build go1.N build constraints. The go directive now specifies a minimum Go version for the module. Furthermore, it sets the language version that is in effect, which may change the semantics of Go code. For example, before Go 1.22, loop variables were reused across iterations, but since Go 1.22, loop variables only exist for the duration of an iteration. Modules that specify go 1.22 will use the new semantics, while modules that specify an older version will not.

Individual files can both upgrade and downgrade their language version by using //go:build go1.N directives. In a module that requires Go 1.22, a file specifying Go 1.21 will experience the old loop variable semantics, and vice versa. Because the Go module as a whole still specifies a minimum version, even files specifying an older version will have access to the standard library of the minimum version.

Staticcheck 2024.1 takes all of this into consideration when analyzing the behavior of Go code, when determining which checks are applicable, and when making suggestions. Older versions of Staticcheck were already aware of Go versions, but 2024.1 works on a more fine-grained, per-file basis, and differentiates between the pre- and post-1.21 semantics of the go directive.

The -go command line flag continues to exist. It will override any module-based version selection. This is primarily useful for Go modules that target older Go versions (because here, the go directive didn’t specify a minimum version), or when working outside of Go modules.

To prevent misinterpreting code, Staticcheck now refuses to analyze modules that require a version of Go that is newer than that with which Staticcheck was built.

Checks

New checks

The following checks have been added:

  • SA1031 flags overlapping destination and source slices passed to certain encoding functions.
  • SA1032 flags calls to errors.Is where the two arguments have been swapped.
  • SA4032 flags impossible comparisons of runtime.GOOS and runtime.GOARCH based on the file’s build tags.
  • SA6006 flags io.WriteString(w, string(b)) as it would be both simpler and more efficient to use w.Write(b).
  • SA9009 flags comments that look like they intend to be compiler directives but which aren’t due to extraneous whitespace.

Changed checks

The following checks have been improved:

  • QF1001 no longer panics on expressions involving “key: value” pairs (issue 1484).
  • S1008 now understands that some built-in functions never return negative values. For example, it now negates len(x) > 0 as len(x) == 0 (issue 1422).
  • S1009 now flags unnecessary nil checks that involve selector expressions (issue 1527).
  • S1017 no longer flags if else branches (issue 1447).
  • SA1006 now detects more Printf-like functions from the standard library (issue 1528).
  • SA1015 now skips any code targeting Go 1.23 or newer (issue 1558).
  • SA1029 now flags uses of the empty struct (struct{}) as context keys (issue 1504).
  • SA4003 now flags pointless integer comparisons that involve literals, not just constants from the math package (issue 1470).
  • SA4015 now supports conversions that involve generics.
  • SA4023 no longer panics on type sets that contain arrays (issue 1397).
  • SA5001 now emits a clearer message (issue 1489).
  • SA9003 has been disabled by default because of too many noisy positives (issue 321).
  • ST1000 now permits punctuation following the package name, as in “Package pkg, which …” (issue 1452).
  • ST1018 now accepts variation selectors in emoji and certain Arabic formatting characters in string literals (issue 1456).
  • ST1020 no longer flags comments that start with a deprecation notice (issue 1378).
  • U1000 handles generic interfaces slightly better, reducing the number of false positives.
  • Due to improvements in the intermediate representation, various checks may now detect more problems.

Miscellaneous changes and fixes

  • The keyify utility has been deleted. This functionality is provided by gopls nowadays.
  • staticcheck -merge now exits with a non-zero exit status if any problems were found. This matches the behavior of non-merge uses.
  • Malformed staticcheck.conf files now cause more useful errors to be emitted.
  • Labeled statements with blank labels no longer cause panics.
  • Functions with named return parameters that never actually return no longer cause panics (issue 1533).

Staticcheck 2024.1rc1 (v0.5.0-rc.1)

Pre-release

Choose a tag to compare

@dominikh dominikh released this 01 Jul 20:06
2024.1rc1

This is a release candidate of Staticcheck 2024.1. It has been built with Go 1.23rc1 and supports analyzing Go 1.23 code, including range-over-func iterators.

Backwards incompatible changes

Staticcheck 2024.1 contains the following backwards incompatible changes:

  • The keyify utility has been removed. The recommended alternative is gopls.
  • staticcheck -merge now exits with a non-zero status if any problems have been found.

Improved Go 1.22 support

This release updates Staticcheck’s database of deprecated standard library APIs to cover the Go 1.22 release. Furthermore, checks have been updated to correctly handle the new “for” loop variable scoping behavior as well as ranging over integers.

Added Go 1.23 support

Staticcheck 2024.1 has full support for iterators / range-over-func. Furthermore, SA1015 will skip any code targeting Go 1.23 or newer, as it is now possible to use time.Tick without leaking memory.

Improved handling of Go versions

Go 1.21 more rigorously defined the meaning of the go directive in go.mod files, as well as its interactions with //go:build go1.N build constraints. The go directive now specifies a minimum Go version for the module. Furthermore, it sets the language version that is in effect, which may change the semantics of Go code. For example, before Go 1.22, loop variables were reused across iterations, but since Go 1.22, loop variables only exist for the duration of an iteration. Modules that specify go 1.22 will use the new semantics, while modules that specify an older version will not.

Individual files can both upgrade and downgrade their language version by using //go:build go1.N directives. In a module that requires Go 1.22, a file specifying Go 1.21 will experience the old loop variable semantics, and vice versa. Because the Go module as a whole still specifies a minimum version, even files specifying an older version will have access to the standard library of the minimum version.

Staticcheck 2024.1 takes all of this into consideration when analyzing the behavior of Go code, when determining which checks are applicable, and when making suggestions. Older versions of Staticcheck were already aware of Go versions, but 2024.1 works on a more fine-grained, per-file basis, and differentiates between the pre- and post-1.21 semantics of the go directive.

The -go command line flag continues to exist. It will override any module-based version selection. This is primarily useful for Go modules that target older Go versions (because here, the go directive didn’t specify a minimum version), or when working outside of Go modules.

To prevent misinterpreting code, Staticcheck now refuses to analyze modules that require a version of Go that is newer than that with which Staticcheck was built.

Checks

New checks

The following checks have been added:

  • SA1031 flags overlapping destination and source slices passed to certain encoding functions.
  • SA1032 flags calls to errors.Is where the two arguments have been swapped.
  • SA4032 flags impossible comparisons of runtime.GOOS and runtime.GOARCH based on the file’s build tags.
  • SA6006 flags io.WriteString(w, string(b)) as it would be both simpler and more efficient to use w.Write(b).
  • SA9009 flags comments that look like they intend to be compiler directives but which aren’t due to extraneous whitespace.

Changed checks

The following checks have been improved:

  • QF1001 no longer panics on expressions involving “key: value” pairs (issue 1484).
  • S1008 now understands that some built-in functions never return negative values. For example, it now negates len(x) > 0 as len(x) == 0 (issue 1422).
  • S1009 now flags unnecessary nil checks that involve selector expressions (issue 1527).
  • S1017 no longer flags if else branches (issue 1447).
  • SA1006 now detects more Printf-like functions from the standard library (issue 1528).
  • SA1015 now skips any code targeting Go 1.23 or newer (issue 1558).
  • SA1029 now flags uses of the empty struct (struct{}) as context keys (issue 1504).
  • SA4003 now flags pointless integer comparisons that involve literals, not just constants from the math package (issue 1470).
  • SA4015 now supports conversions that involve generics.
  • SA4023 no longer panics on type sets that contain arrays (issue 1397).
  • SA5001 now emits a clearer message (issue 1489).
  • SA9003 has been disabled by default because of too many noisy positives (issue 321).
  • ST1000 now permits punctuation following the package name, as in “Package pkg, which …” (issue 1452).
  • ST1018 now accepts variation selectors in emoji and certain Arabic formatting characters in string literals (issue 1456).
  • ST1020 no longer flags comments that start with a deprecation notice (issue 1378).
  • U1000 handles generic interfaces slightly better, reducing the number of false positives.
  • Due to improvements in the intermediate representation, various checks may now detect more problems.

Miscellaneous changes and fixes

  • The keyify utility has been deleted. This functionality is provided by gopls nowadays.
  • staticcheck -merge now exits with a non-zero exit status if any problems were found. This matches the behavior of non-merge uses.
  • Malformed staticcheck.conf files now cause more useful errors to be emitted.
  • Labeled statements with blank labels no longer cause panics.
  • Functions with named return parameters that never actually return no longer cause panics (issue 1533).

Staticcheck 2023.1.7 (v0.4.7)

Choose a tag to compare

@dominikh dominikh released this 22 Feb 13:36
2023.1.7

This release fixes some minor issues in Staticcheck’s intermediate representation. Furthermore, it improves the way QF1003 generates suggested fixes, working around constraints in the language server protocol.

The released binaries for this version have been built with Go 1.22 and should no longer panic when checking code targeting Go 1.22.

Staticcheck 2023.1.6 (v0.4.6)

Choose a tag to compare

@dominikh dominikh released this 13 Sep 10:25
2023.1.6

This release fixes the following bugs:

Staticcheck 2023.1.5 (v0.4.5)

Choose a tag to compare

@dominikh dominikh released this 17 Aug 16:25
2023.1.5

This release fixes the following bug:

  • A crash involving methods named _