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.
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.
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.
Numerous new checks have been added in this release:
net/http.CanonicalHeaderKey
.fmt.Sprintf
, such as fmt.Println(fmt.Sprintf(...))
.fmt.Sprint
with single string literals.sort.Slice
on non-slices.if &x == nil
.{{ check "ST1020" }}, {{ check "ST1021" }} and {{ check "ST1022" }} are not enabled by default.
Several checks have been improved:
v.String()
instead of fmt.Sprintf("%s", v)
when v
is a reflect.Value
. fmt
gives special treatment to reflect.Value
and the two results differ.time.Tick
in packages that implement Cobra commands.x == x
and x != x
when `x` has a compound type involving floats.x <= 0
when x
is an unsigned integer. While it is true that x <= 0
can be written more specifically as x == 0
, this is not a helpful suggestion in reality. A lot of people use x <= 0
as a defensive measure, in case x
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.x & k
where k
is defined as const k = iota
.x[fn()] = x[fn()]
if fn
isn't pure.github.com/jessevdk/go-flags
.unsafe.Pointer
is a pointer type that can be used with verbs such as %p
. Furthermore, it validates calls to golang.org/x/xerrors.Errorf
.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.The following bugs were fixed:
staticcheck
no longer fails to check packages that consist exclusively of tests.
The 2020.1 release neglected to update the version string stored in
the binary, causing staticcheck -version
to incorrectly emit (no version)
.
The 2020.1.1 release incorrectly identified itself as version 2020.1.
This release fixes two bugs involving //lint:ignore
directives:
this linter directive didn't match anythingreport would either be missing, or be wildly incorrect.
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.
This release fixes a crash in the pattern matching engine and a false positive in SA4006.