1 <ul class="changes-toc">
2 <li><a href="#performance">Performance improvements</a></li>
3 <li><a href="#go-analysis">The go/analysis framework</a></li>
4 <li><a href="#cli">Improvements to the CLI</a><ul>
5 <li><a href="#cli-siginfo">SIGINFO handler</a></li>
6 <li><a href="#cli-explain">Explaining checks</a></li>
7 <li><a href="#cli-debug-version">-debug.version</a></li>
8 <li><a href="#cli-unused">Enabling unused's whole program mode</a></li>
9 <li><a href="#cli-ranges">Range information in diagnostics</a></li>
12 <li><a href="#module">Installing staticcheck as a module</a></li>
13 <li><a href="#deprecated">Removal of deprecated functionality</a></li>
14 <li><a href="#checks">Checks</a><ul>
15 <li><a href="#checks-new">New checks</a></li>
16 <li><a href="#checks-changed">Changed checks</a></li>
18 <li><a href="#sustainable-open-source">Sustainable open source and a personal plea</a></li>
19 <li><a href="#2019.2.1">Staticcheck 2019.2.1 release notes</a></li>
20 <li><a href="#2019.2.2">Staticcheck 2019.2.2 release notes</a></li>
21 <li><a href="#2019.2.3">Staticcheck 2019.2.3 release notes</a></li>
24 <h2 id="performance">Performance improvements</h2>
27 Staticcheck 2019.2 brings major performance improvements and a
28 reduction in memory usage.
32 Staticcheck has been redesigned to only keep those packages in memory that are actively being processed.
33 This allows for much larger workspaces to be checked in one go.
34 While previously it may have been necessary to split a list of packages into many invocations of staticcheck,
35 this is now handled intelligently and efficiently by staticcheck itself.
39 In particular, memory usage is now closely tied to parallelism:
40 having more CPU cores available allows for more packages to be processed in parallel,
41 which increases the number of packages held in memory at any one time.
42 Not only does this make good use of available resources –
43 systems with more CPU cores also tend to have more memory available –
44 it also exposes a single, easy to use knob for trading execution time for memory use.
45 By setting <code>GOMAXPROCS</code> to a value lower than the number of available cores,
46 memory usage of staticcheck will be reduced, at the cost of taking longer to complete.
50 We've observed reductions in memory usage of 2x to 8x when checking large code bases.
65 <td>3.543 s / 677 MB</td>
66 <td>3.747 s / 254 MB</td>
67 <td>+5.76% / -62.48%</td>
72 <td>1.628 s / 294 MB</td>
73 <td>1.678 s / 118 MB</td>
74 <td>+3.07% / -59.86%</td>
79 <td>1.304 s / 225 MB</td>
80 <td>1.702 s / 138 MB</td>
81 <td>+30.52% / -38.67%</td>
86 <td>26.234 s / 3987 MB</td>
87 <td>19.444 s / 1054 MB</td>
88 <td>-25.88% / -73.56%</td>
92 <td>github.com/cockroachdb/cockroach/pkg/...</td>
93 <td>88.644 s / 15959 MB</td>
94 <td>93.798 s / 4156 MB</td>
95 <td>+5.81% / -73.96%</td>
101 ¹: The fact cache was empty for all benchmarks.
108 In addition, staticcheck now employs caching to speed up repeated checking of packages.
109 In the past, when checking a package, all of its dependencies had to be loaded from source and analyzed.
110 Now, we can make use of Go's build cache, as well as cache our own analysis facts.
111 This makes staticcheck behave a lot more like go build, where repeated builds are much faster.
114 <table class="table">
126 <td>3.747 s / 254 MB</td>
127 <td>1.545 s / 195 MB</td>
128 <td>-58.77% / -23.23%</td>
133 <td>1.678 s / 118 MB</td>
134 <td>0.495 s / 57 MB</td>
135 <td>-70.5% / -51.69%</td>
140 <td>1.702 s / 138 MB</td>
141 <td>0.329 s / 31 MB</td>
142 <td>-80.67% / -77.54%</td>
147 <td>19.444 s / 1054 MB</td>
148 <td>15.099 s / 887 MB</td>
149 <td>-22.35% / -15.84%</td>
153 <td>github.com/cockroachdb/cockroach/pkg/...</td>
154 <td>93.798 s / 4156 MB</td>
155 <td>47.205 s / 2516 MB</td>
156 <td>-49.67% / -39.46%</td>
161 This combination of improvements not only compensates for the
162 increased memory usage that 2019.1 introduced, it also brings the
163 memory usage and execution times way below the levels of those seen in the
164 2017.2 release, which had previously been our most efficient
169 It should be noted that all of these improvements are part of the <em>staticcheck</em> command itself, not the individual checks.
170 Tools such as golangci-lint will have to replicate our efforts to benefit from these improvements.
173 <h2 id="go-analysis">The go/analysis framework</h2>
176 Part of the redesign of staticcheck involved porting our code to the <a href="https://godoc.org/golang.org/x/tools/go/analysis">go/analysis</a> framework.
180 The go/analysis framework is a framework for writing static analysis tools such as staticcheck and go vet.
181 It provides an API that enables interoperability between different analyses and analysis drivers – drivers being the code that actually executes analyses.
182 The intention is that any driver can trivially use any analysis that is implemented using go/analysis.
186 With the exception of {{ check "U1000" }}, all of our checks are now go/analysis analyses. Furthermore, the <em>staticcheck</em> command is now a go/analysis driver.
190 With our move to this framework, we enable other drivers to reuse our checks without having to patch them.
191 This should be of particular interest to golangci-lint, which previously took to patching staticcheck, sometimes in subtly incorrect ways.
192 Another high-profile go/analysis driver is gopls, the Go language server. It will now be much easier for gopls to use staticcheck to analyze code, should it so desire.
196 Theoretically it would also allow us to use third-party analyses as part of staticcheck.
197 Due to quality control reasons, however, we will likely refrain from doing so.
198 Nonetheless it would be trivial for users to maintain internal forks of cmd/staticcheck that use third-party analyses.
201 <h2 id="cli">Improvements to the CLI</h2>
204 We've made several minor improvements to the command-line interface of staticcheck that improve usability and debuggability.
207 <h3 id="cli-siginfo">SIGINFO handler</h3>
210 Upon receiving the SIGINFO signal – or SIGUSR1 on platforms that lack
211 SIGINFO – staticcheck will dump statistics, such as the current phase
212 and how many packages are left to analyze.
216 Packages: 37/619 initial, 38/1011 total; Workers: 8/8; Problems: 73
219 <h3 id="cli-explain">Explaining checks</h3>
222 Using the new <code>-explain</code> flag, a check's documentation can be displayed right in the terminal,
223 eliminating the need to browse to <a href="https://staticcheck.io/docs/checks">https://staticcheck.io/docs/checks</a>.
227 $ staticcheck -explain S1007
228 Simplify regular expression by using raw string literal
230 Raw string literals use ` instead of " and do not support
231 any escape sequences. This means that the backslash (\) can be used
232 freely, without the need of escaping.
234 Since regular expressions have their own escape sequences, raw strings
235 can improve their readability.
239 regexp.Compile("\\A(\\w+) profile: total \\d+\\n\\z")
243 regexp.Compile(`\A(\w+) profile: total \d+\n\z`)
249 <h3 id="cli-debug-version">-debug.version</h3>
252 The <code>-debug.version</code> flag causes staticcheck to print
253 detailed version information, such as the Go version used to compile
254 it, as well as the versions of all dependencies if built using Go
255 modules. This feature is intended for debugging issues, and we will
256 ask for its output from users who file issues.
260 $ staticcheck -debug.version
261 staticcheck (devel, v0.0.0-20190602125119-5a4a2f4a438d)
263 Compiled with Go version: go1.12.5
265 honnef.co/go/tools@v0.0.0-20190602125119-5a4a2f4a438d (sum: h1:U5vSGN1Bjr0Yd/4pRcp8iRUCs3S5TIPzoAeTEFV2aiU=)
267 github.com/BurntSushi/toml@v0.3.1 (sum: h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=)
268 golang.org/x/tools@v0.0.0-20190530171427-2b03ca6e44eb (sum: h1:mnQlcVx8Qq8L70HV0DxUGuiuAtiEHTwF1gYJE/EL9nU=)
271 <h3 id="cli-unused">Enabling unused's whole program mode</h3>
274 When we merged <em>unused</em> into <em>staticcheck</em>, we lost the ability to specify the <code>-exported</code> flag to report unused exported identifiers.
275 Staticcheck 2019.2 restores this ability with the new <code>-unused.whole-program</code> flag.
278 <h3 id="cli-ranges">Range information in diagnostics</h3>
281 Many of our checks now emit <code>[start, end]</code> ranges for findings instead of just positions.
282 These ranges can be accessed via the <code>json</code> output formatter, as well as by using <code>go/analysis.Diagnostic</code> directly, such as in gopls.
286 Note that not all checks are able to emit range information.
289 <h2 id="module">Installing staticcheck as a module</h2>
292 As part of the 2019.2 release, we've turned staticcheck into a Go module.
293 From now on, if using Go modules, you can install specific versions of staticcheck with <code>go get honnef.co/go/tools/cmd/staticcheck@<version></code>,
294 though do note that older releases do not have a <code>go.mod</code> file.
295 You can still download them as modules, but Go will record indirect dependencies in the main module's <code>go.mod</code> file, and no minimum versions are specified.
299 Staticcheck will not use Semantic Versioning for its releases.
300 It is our belief that Semver is a poor fit for applications and is more suited towards libraries.
301 For example, almost every release of staticcheck has backwards incompatible changes to some APIs that aren't meant for public consumption,
302 but which we expose nevertheless so that tinkerers can use them.
306 However, we use so-called <em>pre-release versions</em> of the form <code>v0.0.0-2019.2</code>.
307 These allow us to embed our versioning scheme in that of Semver, with correct sorting and updating of versions.
308 Furthermore, these versions ensure that <code>go get ...</code>,
309 if not specifying an explicit version (that is, if using the query <code>latest</code>),
310 will install the latest released version of staticcheck and not the master branch.
314 While you can use these pre-release version numbers directly, you can also use the canonical versions of the form <code>2019.2</code> instead.
315 The Go tool will automatically translate these versions to the appropriate pre-releases.
319 To install the master branch, use <code>go get honnef.co/go/tools/cmd/staticcheck@master</code>
322 <h2 id="deprecated">Removal of deprecated functionality</h2>
325 Staticcheck 2019.1 deprecated the <em>unused</em>, <em>gosimple</em>, and <em>megacheck</em>
326 utilities, as they have been merged into <em>staticcheck</em>. Furthermore, it deprecated the <code>-ignore</code> flag,
327 which has been replaced by <a href="/docs/#ignoring-problems">linter directives</a>.
331 This release no longer includes these deprecated utilities, nor does
332 it provide the deprecated flag.
335 <h2 id="checks">Checks</h2>
337 <h3 id="checks-new">New checks</h3>
340 Numerous new checks have been added in this release:
344 <li>{{ check "S1033" }} flags unnecessary guards around calls to <code>delete</code>.</li>
345 <li>{{ check "S1034" }} simplifies type switches involving redundant type assertions.</li>
346 <li>{{ check "SA1026" }} flags attempts at marshaling invalid types.</li>
347 <li>{{ check "SA1027" }} flags incorrectly aligned atomic accesses.</li>
348 <li>{{ check "SA4020" }} flags unreachable case clauses in type switches.</li>
349 <li>{{ check "SA4021" }} flags calls to append with a single argument, as <code>x = append(y)</code> is equivalent to <code>x = y</code>.</li>
350 <li>{{ check "SA5008" }} flags certain kinds of invalid struct tags.</li>
351 <li>{{ check "SA5009" }} verifies the correctness of Printf calls.</li>
352 <li>{{ check "SA6005" }} flags inefficient string comparisons involving <code>strings.ToLower</code>
353 or <code>strings.ToUpper</code> when they can be replaced with <code>strings.EqualFold</code>.
355 <li>{{ check "SA9005" }} flags attempts at marshaling structs with no public fields nor custom marshaling.</li>
356 <li>{{ check "ST1017" }} flags so-called <a href="https://en.wikipedia.org/wiki/Yoda_conditions">yoda conditions</a>,
357 which take the form of <code>if 42 == x</code>.
359 <li>{{ check "ST1018" }} flags string literals containing zero-width characters.</li>
363 <h3 id="checks-changed">Changed checks</h3>
366 Several checks have been improved:
370 <li>{{ check "SA1019" }} now flags imports of deprecated packages.</li>
371 <li>{{ check "SA4000" }} no longer flags comparisons between custom float types. Additionally, it avoids a false positive caused by cgo.</li>
372 <li>{{ check "SA4006" }} no longer flags unused values in code generated by goyacc. This avoids noise caused by the nature of the generated state machine.</li>
373 <li>{{ check "ST1005" }} no longer flags error messages that start with capitalized type names.</li>
374 <li>{{ check "ST1006" }} no longer flags receiver names in generated code.</li>
375 <li>{{ check "SA5002" }} no longer suggests replacing <code>for false {</code> with <code>for {</code>.</li>
376 <li>Added "SIP" and "RTP" as default initialisms to {{ check "ST1003" }}.</li>
377 <li>{{ check "SA1006" }}, {{ check "SA4003" }}, {{ check "S1017" }}, and {{ check "S1020" }} match more code patterns.</li>
378 <li>{{ check "S1021" }} is less eager to merge declarations and assignments when multiple assignments are involved.</li>
379 <li>{{ check "U1000" }} has been rewritten, eliminating a variety of false positives.
382 <h2 id="sustainable-open-source">Sustainable open source and a personal plea</h2>
385 Staticcheck is an open source project developed primarily by me, Dominik Honnef, in my free time.
386 While this model of software development has gotten increasingly common, it is not very sustainable.
387 Time has to be split between open source work and paid work to sustain one's life.
388 This is made especially unfortunate by the fact that hundreds of companies rely on open source each day,
389 but few consider giving back to it, even though it would directly benefit their businesses,
390 ensuring that the software they rely on keeps being developed.
394 I have long been soliciting donations for staticcheck <a href="https://www.patreon.com/dominikh">on Patreon</a> to make its development more sustainable.
395 A fair number of individuals have generously pledged their support and I am very grateful to them.
396 Unfortunately, only few companies support staticcheck's development, and I'd like for that to change.
400 To people who are familiar with Patreon, it might've always seemed like an odd choice for a software project.
401 Patreon focuses on art and creative work, and on individuals supporting said work, not companies.
402 I am therefore excited to announce my participation in <a href="https://github.com/sponsors">GitHub Sponsors</a>,
403 a new way of supporting developers, directly on GitHub.
407 GitHub Sponsors allows you to easily support developers by sponsoring them on a monthly basis, <a href="https://github.com/users/dominikh/sponsorship">via a few simple clicks.</a>
408 It is fully integrated with the platform and can use your existing billing information, making it an effortless process.
409 <strong>To encourage more company sponsorships I offer to display your company's logo prominently on
410 <a href="https://staticcheck.io/">staticcheck's website</a></strong>
412 <a href="https://github.com/users/dominikh/sponsorship?utf8=%E2%9C%93&tier_id=MDIyOk1hcmtldHBsYWNlTGlzdGluZ1BsYW4yNTAy&editing=false">$250 USD a month</a>,
413 to show my appreciation for your contribution and to show to the world how much you care about code quality.
417 Please don't hesitate <a href="mailto:dominik@honnef.co">contacting me directly</a> if neither GitHub Sponsors nor Patreon seem suitable to you but you'd like to support me nevertheless.
418 I am sure we can work something out.
421 <h2 id="2019.2.1">Staticcheck 2019.2.1 release notes</h2>
424 The 2019.2 release has an unfortunate bug that prevents staticcheck from running on 32-bit architectures, causing it to crash unconditionally.
425 This release fixes that crash.
428 <h2 id="2019.2.2">Staticcheck 2019.2.2 release notes</h2>
431 Staticcheck 2019.2.2 contains the following user-visible fixes:
435 <li>{{ check "S1008" }} now skips if/else statements where both branches return the same value.</li>
436 <li>{{ check "SA4006" }} now considers a value read when a switch statement reads it, even if the switch statement has no branches.</li>
437 <li>2019.2 introduced a bug that made it impossible to enable non-default checks via configuration files. This is now possible again.</li>
438 <li>2019.2 introduced a bug that made the <code>-tags</code> command line argument ineffective, making it impossible to pass in build tags. This is now possible again.</li>
439 <li>From this release onward, we will use pseudo versions of the form
440 <code>v0.0.<strong>1</strong>-<year>.<minor></code> instead of <code>v0.0.<strong>0</strong>-<year>.<minor></code>.
441 This fixes an issue where <code>go get</code> would prefer an older commit over a newer released version due to the way versions sort.
445 <h2 id="2019.2.3">Staticcheck 2019.2.3 release notes</h2>
448 Staticcheck 2019.2.3 is a re-release of 2019.2.2.
449 Its pre-built binaries, which can be found on GitHub,
450 have been built with Go 1.13, to enable checking of code that uses language features introduced in Go 1.13.