3 import "honnef.co/go/tools/lint"
5 var Docs = map[string]*lint.Documentation{
7 Title: `Invalid regular expression`,
12 Title: `Invalid template`,
17 Title: `Invalid format in time.Parse`,
22 Title: `Unsupported argument to functions in encoding/binary`,
23 Text: `The encoding/binary package can only serialize types with known sizes.
24 This precludes the use of the int and uint types, as their sizes
25 differ on different architectures. Furthermore, it doesn't support
26 serializing maps, channels, strings, or functions.
28 Before Go 1.8, bool wasn't supported, either.`,
33 Title: `Suspiciously small untyped constant in time.Sleep`,
34 Text: `The time.Sleep function takes a time.Duration as its only argument.
35 Durations are expressed in nanoseconds. Thus, calling time.Sleep(1)
36 will sleep for 1 nanosecond. This is a common source of bugs, as sleep
37 functions in other languages often accept seconds or milliseconds.
39 The time package provides constants such as time.Second to express
40 large durations. These can be combined with arithmetic to express
41 arbitrary durations, for example '5 * time.Second' for 5 seconds.
43 If you truly meant to sleep for a tiny amount of time, use
44 'n * time.Nanosecond' to signal to Staticcheck that you did mean to sleep
45 for some amount of nanoseconds.`,
50 Title: `Invalid first argument to exec.Command`,
51 Text: `os/exec runs programs directly (using variants of the fork and exec
52 system calls on Unix systems). This shouldn't be confused with running
53 a command in a shell. The shell will allow for features such as input
54 redirection, pipes, and general scripting. The shell is also
55 responsible for splitting the user's input into a program name and its
56 arguments. For example, the equivalent to
62 exec.Command("ls", "/", "/tmp")
64 If you want to run a command in a shell, consider using something like
65 the following – but be aware that not all systems, particularly
66 Windows, will have a /bin/sh program:
68 exec.Command("/bin/sh", "-c", "ls | grep Awesome")`,
73 Title: `Printf with dynamic first argument and no further arguments`,
74 Text: `Using fmt.Printf with a dynamic first argument can lead to unexpected
75 output. The first argument is a format string, where certain character
76 combinations have special meaning. If, for example, a user were to
77 enter a string such as
81 and you printed it with
85 it would lead to the following output:
87 Interest rate: 5%!(NOVERB).
89 Similarly, forming the first parameter via string concatenation with
90 user input should be avoided for the same reason. When printing user
91 input, either use a variant of fmt.Print, or use the %s Printf verb
92 and pass the string as an argument.`,
97 Title: `Invalid URL in net/url.Parse`,
102 Title: `Non-canonical key in http.Header map`,
103 Text: `Keys in http.Header maps are canonical, meaning they follow a specific
104 combination of uppercase and lowercase letters. Methods such as
105 http.Header.Add and http.Header.Del convert inputs into this canonical
106 form before manipulating the map.
108 When manipulating http.Header maps directly, as opposed to using the
109 provided methods, care should be taken to stick to canonical form in
110 order to avoid inconsistencies. The following piece of code
111 demonstrates one such inconsistency:
114 h["etag"] = []string{"1234"}
115 h.Add("etag", "5678")
119 // map[Etag:[5678] etag:[1234]]
121 The easiest way of obtaining the canonical form of a key is to use
122 http.CanonicalHeaderKey.`,
127 Title: `(*regexp.Regexp).FindAll called with n == 0, which will always return zero results`,
128 Text: `If n >= 0, the function returns at most n matches/submatches. To
129 return all results, specify a negative number.`,
134 Title: `Various methods in the strings package expect valid UTF-8, but invalid input is provided`,
139 Title: `A nil context.Context is being passed to a function, consider using context.TODO instead`,
144 Title: `io.Seeker.Seek is being called with the whence constant as the first argument, but it should be the second`,
149 Title: `Non-pointer value passed to Unmarshal or Decode`,
154 Title: `Using time.Tick in a way that will leak. Consider using time.NewTicker, and only use time.Tick in tests, commands and endless functions`,
159 Title: `Trapping a signal that cannot be trapped`,
160 Text: `Not all signals can be intercepted by a process. Speficially, on
161 UNIX-like systems, the syscall.SIGKILL and syscall.SIGSTOP signals are
162 never passed to the process, but instead handled directly by the
163 kernel. It is therefore pointless to try and handle these signals.`,
168 Title: `Channels used with os/signal.Notify should be buffered`,
169 Text: `The os/signal package uses non-blocking channel sends when delivering
170 signals. If the receiving end of the channel isn't ready and the
171 channel is either unbuffered or full, the signal will be dropped. To
172 avoid missing signals, the channel should be buffered and of the
173 appropriate size. For a channel used for notification of just one
174 signal value, a buffer of size 1 is sufficient.`,
179 Title: `strings.Replace called with n == 0, which does nothing`,
180 Text: `With n == 0, zero instances will be replaced. To replace all
181 instances, use a negative number, or use strings.ReplaceAll.`,
186 Title: `Using a deprecated function, variable, constant or field`,
191 Title: `Using an invalid host:port pair with a net.Listen-related function`,
196 Title: `Using bytes.Equal to compare two net.IP`,
197 Text: `A net.IP stores an IPv4 or IPv6 address as a slice of bytes. The
198 length of the slice for an IPv4 address, however, can be either 4 or
199 16 bytes long, using different ways of representing IPv4 addresses. In
200 order to correctly compare two net.IPs, the net.IP.Equal method should
201 be used, as it takes both representations into account.`,
206 Title: `Modifying the buffer in an io.Writer implementation`,
207 Text: `Write must not modify the slice data, even temporarily.`,
212 Title: `A string cutset contains duplicate characters`,
213 Text: `The strings.TrimLeft and strings.TrimRight functions take cutsets, not
214 prefixes. A cutset is treated as a set of characters to remove from a
217 strings.TrimLeft("42133word", "1234"))
219 will result in the string "word" – any characters that are 1, 2, 3 or
220 4 are cut from the left of the string.
222 In order to remove one string from another, use strings.TrimPrefix instead.`,
227 Title: `It is not possible to use (*time.Timer).Reset's return value correctly`,
232 Title: `Cannot marshal channels or functions`,
237 Title: `Atomic access to 64-bit variable must be 64-bit aligned`,
238 Text: `On ARM, x86-32, and 32-bit MIPS, it is the caller's responsibility to
239 arrange for 64-bit alignment of 64-bit words accessed atomically. The
240 first word in a variable or in an allocated struct, array, or slice
241 can be relied upon to be 64-bit aligned.
243 You can use the structlayout tool to inspect the alignment of fields
249 Title: `sort.Slice can only be used on slices`,
250 Text: `The first argument of sort.Slice must be a slice.`,
255 Title: `Inappropriate key in call to context.WithValue`,
256 Text: `The provided key must be comparable and should not be
257 of type string or any other built-in type to avoid collisions between
258 packages using context. Users of WithValue should define their own
261 To avoid allocating when assigning to an interface{},
262 context keys often have concrete type struct{}. Alternatively,
263 exported context key variables' static type should be a pointer or
269 Title: `sync.WaitGroup.Add called inside the goroutine, leading to a race condition`,
274 Title: `Empty critical section, did you mean to defer the unlock?`,
275 Text: `Empty critical sections of the kind
280 are very often a typo, and the following was intended instead:
285 Do note that sometimes empty critical sections can be useful, as a
286 form of signaling to wait on another goroutine. Many times, there are
287 simpler ways of achieving the same effect. When that isn't the case,
288 the code should be amply commented to avoid confusion. Combining such
289 comments with a //lint:ignore directive can be used to suppress this
290 rare false positive.`,
295 Title: `Called testing.T.FailNow or SkipNow in a goroutine, which isn't allowed`,
300 Title: `Deferred Lock right after locking, likely meant to defer Unlock instead`,
305 Title: `TestMain doesn't call os.Exit, hiding test failures`,
306 Text: `Test executables (and in turn 'go test') exit with a non-zero status
307 code if any tests failed. When specifying your own TestMain function,
308 it is your responsibility to arrange for this, by calling os.Exit with
309 the correct code. The correct code is returned by (*testing.M).Run, so
310 the usual way of implementing TestMain is to end it with
316 Title: `Assigning to b.N in benchmarks distorts the results`,
317 Text: `The testing package dynamically sets b.N to improve the reliability of
318 benchmarks and uses it in computations to determine the duration of a
319 single operation. Benchmark code must not alter b.N as this would
325 Title: `Boolean expression has identical expressions on both sides`,
330 Title: `&*x gets simplified to x, it does not copy x`,
335 Title: `Comparing strings with known different sizes has predictable results`,
340 Title: `Comparing unsigned values against negative values is pointless`,
345 Title: `The loop exits unconditionally after one iteration`,
350 Title: `Field assignment that will never be observed. Did you mean to use a pointer receiver?`,
355 Title: `A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?`,
360 Title: `The variable in the loop condition never changes, are you incrementing the wrong variable?`,
365 Title: `A function argument is overwritten before its first use`,
370 Title: `The result of append will never be observed anywhere`,
375 Title: `Break statement with no effect. Did you mean to break out of an outer loop?`,
380 Title: `Comparing a value against NaN even though no value is equal to NaN`,
385 Title: `Negating a boolean twice (!!b) is the same as writing b. This is either redundant, or a typo.`,
390 Title: `An if/else if chain has repeated conditions and no side-effects; if the condition didn't match the first time, it won't match the second time, either`,
395 Title: `Calling functions like math.Ceil on floats converted from integers doesn't do anything useful`,
400 Title: `Certain bitwise operations, such as x ^ 0, do not do anything useful`,
405 Title: `A pure function's return value is discarded, making the call pointless`,
410 Title: `Self-assignment of variables`,
415 Title: `Multiple, identical build constraints in the same file`,
420 Title: `Unreachable case clause in a type switch`,
421 Text: `In a type switch like the following
424 func (T) Read(b []byte) (int, error) { return 0, nil }
426 var v interface{} = T{}
435 the second case clause can never be reached because T implements
436 io.Reader and case clauses are evaluated in source order.
441 func (T) Read(b []byte) (int, error) { return 0, nil }
442 func (T) Close() error { return nil }
444 var v interface{} = T{}
453 Even though T has a Close method and thus implements io.ReadCloser,
454 io.Reader will always match first. The method set of io.Reader is a
455 subset of io.ReadCloser. Thus it is impossible to match the second
456 case without matching the first case.
459 Structurally equivalent interfaces
461 A special case of the previous example are structurally identical
462 interfaces. Given these declarations
467 func doSomething() error {
468 err, ok := doAnotherThing()
476 the following type switch will have an unreachable case clause:
478 switch doSomething().(type) {
485 T will always match before V because they are structurally equivalent
486 and therefore doSomething()'s return value implements both.`,
491 Title: `x = append(y) is equivalent to x = y`,
496 Title: `Comparing the address of a variable against nil`,
497 Text: `Code such as 'if &x == nil' is meaningless, because taking the address of a variable always yields a non-nil pointer.`,
502 Title: `Assignment to nil map`,
507 Title: `Defering Close before checking for a possible error`,
512 Title: `The empty for loop (for {}) spins and can block the scheduler`,
517 Title: `Defers in infinite loops will never execute`,
518 Text: `Defers are scoped to the surrounding function, not the surrounding
519 block. In a function that never returns, i.e. one containing an
520 infinite loop, defers will never execute.`,
525 Title: `for { select { ... with an empty default branch spins`,
530 Title: `The finalizer references the finalized object, preventing garbage collection`,
531 Text: `A finalizer is a function associated with an object that runs when the
532 garbage collector is ready to collect said object, that is when the
533 object is no longer referenced by anything.
535 If the finalizer references the object, however, it will always remain
536 as the final reference to that object, preventing the garbage
537 collector from collecting the object. The finalizer will never run,
538 and the object will never be collected, leading to a memory leak. That
539 is why the finalizer should instead use its first argument to operate
540 on the object. That way, the number of references can temporarily go
541 to zero before the object is being passed to the finalizer.`,
546 Title: `Slice index out of bounds`,
551 Title: `Infinite recursive call`,
552 Text: `A function that calls itself recursively needs to have an exit
553 condition. Otherwise it will recurse forever, until the system runs
556 This issue can be caused by simple bugs such as forgetting to add an
557 exit condition. It can also happen "on purpose". Some languages have
558 tail call optimization which makes certain infinite recursive calls
559 safe to use. Go, however, does not implement TCO, and as such a loop
560 should be used instead.`,
565 Title: `Invalid struct tag`,
570 Title: `Invalid Printf call`,
575 Title: `Impossible type assertion`,
577 Text: `Some type assertions can be statically proven to be
578 impossible. This is the case when the method sets of both
579 arguments of the type assertion conflict with each other, for
580 example by containing the same method with different
583 The Go compiler already applies this check when asserting from an
584 interface value to a concrete type. If the concrete type misses
585 methods from the interface, or if function signatures don't match,
586 then the type assertion can never succeed.
588 This check applies the same logic when asserting from one interface to
589 another. If both interface types contain the same method but with
590 different signatures, then the type assertion can never succeed,
597 Title: `Possible nil pointer dereference`,
599 Text: `A pointer is being dereferenced unconditionally, while
600 also being checked against nil in another place. This suggests that
601 the pointer may be nil and dereferencing it may panic. This is
602 commonly a result of improperly ordered code or missing return
603 statements. Consider the following examples:
608 // This nil check is equally important for the previous dereference
614 func TestFoo(t *testing.T) {
617 t.Errorf("nil pointer received")
620 // t.Errorf does not abort the test, so if x is nil, the next line will panic.
624 Staticcheck tries to deduce which functions abort control flow.
625 For example, it is aware that a function will not continue
626 execution after a call to panic or log.Fatal. However, sometimes
627 this detection fails, in particular in the presence of
628 conditionals. Consider the following example:
630 func Log(msg string, level int) {
632 if level == levelFatal {
637 func Fatal(msg string) {
643 Fatal("unexpected nil pointer")
648 Staticcheck will flag the dereference of x, even though it is perfectly
649 safe. Staticcheck is not able to deduce that a call to
650 Fatal will exit the program. For the time being, the easiest
651 workaround is to modify the definition of Fatal like so:
653 func Fatal(msg string) {
658 We also hard-code functions from common logging packages such as
659 logrus. Please file an issue if we're missing support for a
665 Title: `Using regexp.Match or related in a loop, should use regexp.Compile`,
670 Title: `Missing an optimization opportunity when indexing maps by byte slices`,
672 Text: `Map keys must be comparable, which precludes the use of byte slices.
673 This usually leads to using string keys and converting byte slices to
676 Normally, a conversion of a byte slice to a string needs to copy the data and
677 causes allocations. The compiler, however, recognizes m[string(b)] and
678 uses the data of b directly, without copying it, because it knows that
679 the data can't change during the map lookup. This leads to the
680 counter-intuitive situation that
686 will be less efficient than
688 println(m[string(b)])
689 println(m[string(b)])
691 because the first version needs to copy and allocate, while the second
694 For some history on this optimization, check out commit
695 f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.`,
700 Title: `Storing non-pointer values in sync.Pool allocates memory`,
701 Text: `A sync.Pool is used to avoid unnecessary allocations and reduce the
702 amount of work the garbage collector has to do.
704 When passing a value that is not a pointer to a function that accepts
705 an interface, the value needs to be placed on the heap, which means an
706 additional allocation. Slices are a common thing to put in sync.Pools,
707 and they're structs with 3 fields (length, capacity, and a pointer to
708 an array). In order to avoid the extra allocation, one should store a
709 pointer to the slice instead.
711 See the comments on https://go-review.googlesource.com/c/go/+/24371
712 that discuss this problem.`,
717 Title: `Converting a string to a slice of runes before ranging over it`,
718 Text: `You may want to loop over the runes in a string. Instead of converting
719 the string to a slice of runes and looping over that, you can loop
720 over the string itself. That is,
722 for _, r := range s {}
726 for _, r := range []rune(s) {}
728 will yield the same values. The first version, however, will be faster
729 and avoid unnecessary memory allocations.
731 Do note that if you are interested in the indices, ranging over a
732 string and over a slice of runes will yield different indices. The
733 first one yields byte offsets, while the second one yields indices in
734 the slice of runes.`,
739 Title: `Inefficient string comparison with strings.ToLower or strings.ToUpper`,
740 Text: `Converting two strings to the same case and comparing them like so
742 if strings.ToLower(s1) == strings.ToLower(s2) {
746 is significantly more expensive than comparing them with
747 strings.EqualFold(s1, s2). This is due to memory usage as well as
748 computational complexity.
750 strings.ToLower will have to allocate memory for the new strings, as
751 well as convert both strings fully, even if they differ on the very
752 first byte. strings.EqualFold, on the other hand, compares the strings
753 one character at a time. It doesn't need to create two intermediate
754 strings and can return as soon as the first non-matching character has
757 For a more in-depth explanation of this issue, see
758 https://blog.digitalocean.com/how-to-efficiently-compare-strings-in-go/`,
763 Title: `Defers in range loops may not run when you expect them to`,
768 Title: `Using a non-octal os.FileMode that looks like it was meant to be in octal.`,
773 Title: `Empty body in an if or else branch`,
778 Title: `Only the first constant has an explicit type`,
780 Text: `In a constant declaration such as the following:
787 the constant Second does not have the same type as the constant First.
788 This construct shouldn't be confused with
795 where First and Second do indeed have the same type. The type is only
796 passed on when no explicit value is assigned to the constant.
798 When declaring enumerations with explicit values it is therefore
799 important not to write
802 EnumFirst EnumType = 1
807 This discrepancy in types can cause various confusing behaviors and
811 Wrong type in variable declarations
813 The most obvious issue with such incorrect enumerations expresses
814 itself as a compile error:
823 func fn(useFirst bool) {
830 fails to compile with
832 ./const.go:11:5: cannot use EnumFirst (type uint8) as type int in assignment
837 A more subtle issue occurs with types that have methods and optional
838 interfaces. Consider the following:
846 func (e Enum) String() string {
856 fmt.Println(EnumFirst)
857 fmt.Println(EnumSecond)
860 This code will output
865 as EnumSecond has no explicit type, and thus defaults to int.`,
870 Title: `Trying to marshal a struct with no public fields nor custom marshaling`,
871 Text: `The encoding/json and encoding/xml packages only operate on exported
872 fields in structs, not unexported ones. It is usually an error to try
873 to (un)marshal structs that only consist of unexported fields.
875 This check will not flag calls involving types that define custom
876 marshaling behavior, e.g. via MarshalJSON methods. It will also not
877 flag empty structs.`,