Staticcheck 2020.1 release notes
Introduction to Staticcheck 2020.1
Staticcheck 2020.1 introduces UI improvements, speed enhancements, and a number of new as well as improved checks. Additionally, it is the first release to support the upcoming Go 1.14.
UI improvements
We’ve improved the output of the staticcheck
command as well as
Staticcheck’s integration with gopls to make it easier to understand
the problems that are being reported.
Related information describes the source of a problem, or why Staticcheck believes that there is a problem. Take the following piece of code for example:
func fn(x *int) {
if x == nil {
log.Println("x is nil, returning")
}
// lots of code here
log.Println(*x)
}
Staticcheck 2020.1 will produce the following output:
foo.go:6:14: possible nil pointer dereference (SA5011)
foo.go:2:5: this check suggests that the pointer can be nil
The actual problem that is being reported is the “possible nil pointer
dereference”. Staticcheck also explains why it believes that x
might
be nil, namely the comparison on line 2.
When using the text
or stylish
formatters, related information will
appear as indented lines. The json
formatter adds a new field
related
to problems, containing position information as well as the
message. Editors that use gopls will also display the related
information.
Related information should make it easier to understand why Staticcheck is flagging code, and how to fix problems.
Integration with gopls has seen some other improvements as well¹. We now emit better position information that more accurately reflects the true source of a problem. The most obvious example is that a missing package comment will no longer underline the entire file. Similarly, invalid function arguments will be highlighted individually, instead of highlighting the call as a whole. Finally, some problems can now be automatically fixed by using quick fixes.
¹: due to the nature of Staticcheck’s integration with gopls, gopls will need to update their dependency on Staticcheck before benefiting from these changes.
Better caching
The 2019.2 release introduced caching to Staticcheck, greatly speeding up repeated runs. However, the caching only applied to dependencies; the packages under analysis still had to be analyzed anew on every invocation to compute the list of problems. Staticcheck 2020.1 introduces caching of problems found, so that repeat runs for unchanged packages are virtually instantaneous.
Checks
New checks
Numerous new checks have been added in this release:
- S1035 flags redundant calls to
net/http.CanonicalHeaderKey
. - S1036 flags unnecessary guards around map accesses.
- S1037 flags unnecessarily elaborate ways of sleeping.
- S1038 flags unnecessary uses of
fmt.Sprintf
, such asfmt.Println(fmt.Sprintf(...))
. - S1039 flags uses of
fmt.Sprint
with single string literals. - SA1028 flags uses of
sort.Slice
on non-slices. - SA1029 flags inappropriate keys in calls to context.WithValue.
- SA4022 flags comparisons of the kind
if &x == nil
. - SA5010 flags impossible type assertions.
- SA5011 flags potential nil pointer dereferences.
- ST1019 flags duplicate imports.
- ST1020 checks the documentation of exported functions.
- ST1021 checks the documentation of exported types.
- ST1022 checks the documentation of exported variables and constants.
ST1020, ST1021 and ST1022 are not enabled by default.
Changed checks
Several checks have been improved:
- S1036 detects more kinds of unnecessary guards around map accesses.
- S1008 reports more easily understood diagnostics.
- S1025 no longer suggests using
v.String()
instead offmt.Sprintf("%s", v)
whenv
is areflect.Value
.fmt
gives special treatment toreflect.Value
and the two results differ. - SA1015 no longer flags uses of
time.Tick
in packages that implement Cobra commands. - SA1019 no longer misses references to deprecated packages when said packages have been vendored.
- SA4000 no longer flags comparisons of the kind
x == x
andx != x
whenx
has a compound type involving floats. - SA4003 no longer flags comparisons of the kind
x <= 0
whenx
is an unsigned integer. While it is true thatx <= 0
can be written more specifically asx == 0
, this is not a helpful suggestion in reality. A lot of people usex <= 0
as a defensive measure, in casex
ever becomes signed. Also, unlike all the other warnings made in the check,x <= 0
is neither a tautology nor a contradiction, it is merely less precise than it could be. - SA4016 now detects silly bitwise ops of the form
x & k
wherek
is defined asconst k = iota
. - SA4018 no longer flags self-assignments involving side effects; for example, it won’t flag
x[fn()] = x[fn()]
iffn
isn’t pure. - SA5008 now permits duplicate instances of various struct tags used by
github.com/jessevdk/go-flags
. - SA5009 now correctly recognizes that
unsafe.Pointer
is a pointer type that can be used with verbs such as%p
. Furthermore, it validates calls togolang.org/x/xerrors.Errorf
. - SA5009 now understands
fmt.Printf
verbs that were changed and added in Go 1.13. Specifically, it now recognizes the new%O
verb, and allows the use of%x
and%X
on floats and complex numbers. - ST1003 has learned about several new initialisms.
- ST1011 no longer misses variable declarations with inferred types.
- ST1016 now ignores the names of method receivers of methods declared in generated files.
- ST1020, ST1021, and ST1022 no longer enforce comment style in generated code.
General bug fixes
The following bugs were fixed:
- A race condition in the U1000 check could occasionally lead to sporadic false positives.
- Some files generated by goyacc weren’t recognized as being generated.
staticcheck
no longer fails to check packages that consist exclusively of tests.
Staticcheck 2020.1.1 release notes
The 2020.1 release neglected to update the version string stored in
the binary, causing staticcheck -version
to incorrectly emit (no version)
.
Staticcheck 2020.1.2 release notes
The 2020.1.1 release incorrectly identified itself as version 2020.1.
Staticcheck 2020.1.3 release notes
This release fixes two bugs involving //lint:ignore
directives:
- When ignoring U1000 and checking a package that contains tests, Staticcheck would incorrectly complain that the linter directive didn’t match any problems, even when it did.
- On repeated runs, the position information for a
this linter directive didn’t match anything
report would either be missing, or be wildly incorrect.
Staticcheck 2020.1.4 release notes
This release adds special handling for imports of the
deprecated github.com/golang/protobuf/proto
package.
github.com/golang/protobuf
has deprecated the proto
package, but
their protoc-gen-go
still imports the package and uses
one of its constants, to enforce a weak dependency on a
sufficiently new version of the legacy package
.
Staticcheck would flag the import of this deprecated package in all code generated by protoc-gen-go. Instead of forcing the project to change their project structure, we choose to ignore such imports in code generated by protoc-gen-go. The import still gets flagged in code not generated by protoc-gen-go.
You can find more information about this in the upstream issue.
Staticcheck 2020.1.5 release notes
This release fixes a crash in the pattern matching engine and a false positive in SA4006.
Staticcheck 2020.1.6 release notes
This release makes the following fixes and improvements:
- Staticcheck no longer panics when encountering files that have the following comment:
// Code generated DO NOT EDIT.
- SA4016 no longer panics when checking bitwise operations that involve dot-imported identifiers.
- Fixed the suggested fix offered by S1004.
- Fixed a false positive involving byte arrays in SA5009.
- Fixed a false positive involving named byte slice types in SA5009.
- Added another heuristic to avoid flagging function names in error messages in ST1005.
- SA3000 will no longer flag missing calls to
os.Exit
inTestMain
functions if targeting Go 1.15 or newer.