Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / staticcheck / doc.go
1 package staticcheck
2
3 import "honnef.co/go/tools/lint"
4
5 var Docs = map[string]*lint.Documentation{
6         "SA1000": {
7                 Title: `Invalid regular expression`,
8                 Since: "2017.1",
9         },
10
11         "SA1001": {
12                 Title: `Invalid template`,
13                 Since: "2017.1",
14         },
15
16         "SA1002": {
17                 Title: `Invalid format in time.Parse`,
18                 Since: "2017.1",
19         },
20
21         "SA1003": {
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.
27
28 Before Go 1.8, bool wasn't supported, either.`,
29                 Since: "2017.1",
30         },
31
32         "SA1004": {
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.
38
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.
42
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.`,
46                 Since: "2017.1",
47         },
48
49         "SA1005": {
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
57
58     ls / /tmp
59
60 would be
61
62     exec.Command("ls", "/", "/tmp")
63
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:
67
68     exec.Command("/bin/sh", "-c", "ls | grep Awesome")`,
69                 Since: "2017.1",
70         },
71
72         "SA1006": {
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
78
79     Interest rate: 5%
80
81 and you printed it with
82
83     fmt.Printf(s)
84
85 it would lead to the following output:
86
87     Interest rate: 5%!(NOVERB).
88
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.`,
93                 Since: "2017.1",
94         },
95
96         "SA1007": {
97                 Title: `Invalid URL in net/url.Parse`,
98                 Since: "2017.1",
99         },
100
101         "SA1008": {
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.
107
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:
112
113     h := http.Header{}
114     h["etag"] = []string{"1234"}
115     h.Add("etag", "5678")
116     fmt.Println(h)
117
118     // Output:
119     // map[Etag:[5678] etag:[1234]]
120
121 The easiest way of obtaining the canonical form of a key is to use
122 http.CanonicalHeaderKey.`,
123                 Since: "2017.1",
124         },
125
126         "SA1010": {
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.`,
130                 Since: "2017.1",
131         },
132
133         "SA1011": {
134                 Title: `Various methods in the strings package expect valid UTF-8, but invalid input is provided`,
135                 Since: "2017.1",
136         },
137
138         "SA1012": {
139                 Title: `A nil context.Context is being passed to a function, consider using context.TODO instead`,
140                 Since: "2017.1",
141         },
142
143         "SA1013": {
144                 Title: `io.Seeker.Seek is being called with the whence constant as the first argument, but it should be the second`,
145                 Since: "2017.1",
146         },
147
148         "SA1014": {
149                 Title: `Non-pointer value passed to Unmarshal or Decode`,
150                 Since: "2017.1",
151         },
152
153         "SA1015": {
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`,
155                 Since: "2017.1",
156         },
157
158         "SA1016": {
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.`,
164                 Since: "2017.1",
165         },
166
167         "SA1017": {
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.`,
175                 Since: "2017.1",
176         },
177
178         "SA1018": {
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.`,
182                 Since: "2017.1",
183         },
184
185         "SA1019": {
186                 Title: `Using a deprecated function, variable, constant or field`,
187                 Since: "2017.1",
188         },
189
190         "SA1020": {
191                 Title: `Using an invalid host:port pair with a net.Listen-related function`,
192                 Since: "2017.1",
193         },
194
195         "SA1021": {
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.`,
202                 Since: "2017.1",
203         },
204
205         "SA1023": {
206                 Title: `Modifying the buffer in an io.Writer implementation`,
207                 Text:  `Write must not modify the slice data, even temporarily.`,
208                 Since: "2017.1",
209         },
210
211         "SA1024": {
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
215 string. For example,
216
217     strings.TrimLeft("42133word", "1234"))
218
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.
221
222 In order to remove one string from another, use strings.TrimPrefix instead.`,
223                 Since: "2017.1",
224         },
225
226         "SA1025": {
227                 Title: `It is not possible to use (*time.Timer).Reset's return value correctly`,
228                 Since: "2019.1",
229         },
230
231         "SA1026": {
232                 Title: `Cannot marshal channels or functions`,
233                 Since: "2019.2",
234         },
235
236         "SA1027": {
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.
242
243 You can use the structlayout tool to inspect the alignment of fields
244 in a struct.`,
245                 Since: "2019.2",
246         },
247
248         "SA1028": {
249                 Title: `sort.Slice can only be used on slices`,
250                 Text:  `The first argument of sort.Slice must be a slice.`,
251                 Since: "2020.1",
252         },
253
254         "SA1029": {
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
259 types for keys.
260
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
264 interface.`,
265                 Since: "2020.1",
266         },
267
268         "SA2000": {
269                 Title: `sync.WaitGroup.Add called inside the goroutine, leading to a race condition`,
270                 Since: "2017.1",
271         },
272
273         "SA2001": {
274                 Title: `Empty critical section, did you mean to defer the unlock?`,
275                 Text: `Empty critical sections of the kind
276
277     mu.Lock()
278     mu.Unlock()
279
280 are very often a typo, and the following was intended instead:
281
282     mu.Lock()
283     defer mu.Unlock()
284
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.`,
291                 Since: "2017.1",
292         },
293
294         "SA2002": {
295                 Title: `Called testing.T.FailNow or SkipNow in a goroutine, which isn't allowed`,
296                 Since: "2017.1",
297         },
298
299         "SA2003": {
300                 Title: `Deferred Lock right after locking, likely meant to defer Unlock instead`,
301                 Since: "2017.1",
302         },
303
304         "SA3000": {
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
311 os.Exit(m.Run()).`,
312                 Since: "2017.1",
313         },
314
315         "SA3001": {
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
320 falsify results.`,
321                 Since: "2017.1",
322         },
323
324         "SA4000": {
325                 Title: `Boolean expression has identical expressions on both sides`,
326                 Since: "2017.1",
327         },
328
329         "SA4001": {
330                 Title: `&*x gets simplified to x, it does not copy x`,
331                 Since: "2017.1",
332         },
333
334         "SA4002": {
335                 Title: `Comparing strings with known different sizes has predictable results`,
336                 Since: "2017.1",
337         },
338
339         "SA4003": {
340                 Title: `Comparing unsigned values against negative values is pointless`,
341                 Since: "2017.1",
342         },
343
344         "SA4004": {
345                 Title: `The loop exits unconditionally after one iteration`,
346                 Since: "2017.1",
347         },
348
349         "SA4005": {
350                 Title: `Field assignment that will never be observed. Did you mean to use a pointer receiver?`,
351                 Since: "2017.1",
352         },
353
354         "SA4006": {
355                 Title: `A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?`,
356                 Since: "2017.1",
357         },
358
359         "SA4008": {
360                 Title: `The variable in the loop condition never changes, are you incrementing the wrong variable?`,
361                 Since: "2017.1",
362         },
363
364         "SA4009": {
365                 Title: `A function argument is overwritten before its first use`,
366                 Since: "2017.1",
367         },
368
369         "SA4010": {
370                 Title: `The result of append will never be observed anywhere`,
371                 Since: "2017.1",
372         },
373
374         "SA4011": {
375                 Title: `Break statement with no effect. Did you mean to break out of an outer loop?`,
376                 Since: "2017.1",
377         },
378
379         "SA4012": {
380                 Title: `Comparing a value against NaN even though no value is equal to NaN`,
381                 Since: "2017.1",
382         },
383
384         "SA4013": {
385                 Title: `Negating a boolean twice (!!b) is the same as writing b. This is either redundant, or a typo.`,
386                 Since: "2017.1",
387         },
388
389         "SA4014": {
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`,
391                 Since: "2017.1",
392         },
393
394         "SA4015": {
395                 Title: `Calling functions like math.Ceil on floats converted from integers doesn't do anything useful`,
396                 Since: "2017.1",
397         },
398
399         "SA4016": {
400                 Title: `Certain bitwise operations, such as x ^ 0, do not do anything useful`,
401                 Since: "2017.1",
402         },
403
404         "SA4017": {
405                 Title: `A pure function's return value is discarded, making the call pointless`,
406                 Since: "2017.1",
407         },
408
409         "SA4018": {
410                 Title: `Self-assignment of variables`,
411                 Since: "2017.1",
412         },
413
414         "SA4019": {
415                 Title: `Multiple, identical build constraints in the same file`,
416                 Since: "2017.1",
417         },
418
419         "SA4020": {
420                 Title: `Unreachable case clause in a type switch`,
421                 Text: `In a type switch like the following
422
423     type T struct{}
424     func (T) Read(b []byte) (int, error) { return 0, nil }
425
426     var v interface{} = T{}
427
428     switch v.(type) {
429     case io.Reader:
430         // ...
431     case T:
432         // unreachable
433     }
434
435 the second case clause can never be reached because T implements
436 io.Reader and case clauses are evaluated in source order.
437
438 Another example:
439
440     type T struct{}
441     func (T) Read(b []byte) (int, error) { return 0, nil }
442     func (T) Close() error { return nil }
443
444     var v interface{} = T{}
445
446     switch v.(type) {
447     case io.Reader:
448         // ...
449     case io.ReadCloser:
450         // unreachable
451     }
452
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.
457
458
459 Structurally equivalent interfaces
460
461 A special case of the previous example are structurally identical
462 interfaces. Given these declarations
463
464     type T error
465     type V error
466
467     func doSomething() error {
468         err, ok := doAnotherThing()
469         if ok {
470             return T(err)
471         }
472
473         return U(err)
474     }
475
476 the following type switch will have an unreachable case clause:
477
478     switch doSomething().(type) {
479     case T:
480         // ...
481     case V:
482         // unreachable
483     }
484
485 T will always match before V because they are structurally equivalent
486 and therefore doSomething()'s return value implements both.`,
487                 Since: "2019.2",
488         },
489
490         "SA4021": {
491                 Title: `x = append(y) is equivalent to x = y`,
492                 Since: "2019.2",
493         },
494
495         "SA4022": {
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.`,
498                 Since: "2020.1",
499         },
500
501         "SA5000": {
502                 Title: `Assignment to nil map`,
503                 Since: "2017.1",
504         },
505
506         "SA5001": {
507                 Title: `Defering Close before checking for a possible error`,
508                 Since: "2017.1",
509         },
510
511         "SA5002": {
512                 Title: `The empty for loop (for {}) spins and can block the scheduler`,
513                 Since: "2017.1",
514         },
515
516         "SA5003": {
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.`,
521                 Since: "2017.1",
522         },
523
524         "SA5004": {
525                 Title: `for { select { ... with an empty default branch spins`,
526                 Since: "2017.1",
527         },
528
529         "SA5005": {
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.
534
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.`,
542                 Since: "2017.1",
543         },
544
545         "SA5006": {
546                 Title: `Slice index out of bounds`,
547                 Since: "2017.1",
548         },
549
550         "SA5007": {
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
554 out of memory.
555
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.`,
561                 Since: "2017.1",
562         },
563
564         "SA5008": {
565                 Title: `Invalid struct tag`,
566                 Since: "2019.2",
567         },
568
569         "SA5009": {
570                 Title: `Invalid Printf call`,
571                 Since: "2019.2",
572         },
573
574         "SA5010": {
575                 Title: `Impossible type assertion`,
576
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
581 signatures.
582
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.
587
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,
591 either.`,
592
593                 Since: "2020.1",
594         },
595
596         "SA5011": {
597                 Title: `Possible nil pointer dereference`,
598
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:
604
605     func fn(x *int) {
606         fmt.Println(*x)
607
608         // This nil check is equally important for the previous dereference
609         if x != nil {
610             foo(*x)
611         }
612     }
613
614     func TestFoo(t *testing.T) {
615         x := compute()
616         if x == nil {
617             t.Errorf("nil pointer received")
618         }
619
620         // t.Errorf does not abort the test, so if x is nil, the next line will panic.
621         foo(*x)
622     }
623
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:
629
630     func Log(msg string, level int) {
631         fmt.Println(msg)
632         if level == levelFatal {
633             os.Exit(1)
634         }
635     }
636
637     func Fatal(msg string) {
638         Log(msg, levelFatal)
639     }
640
641     func fn(x *int) {
642         if x == nil {
643             Fatal("unexpected nil pointer")
644         }
645         fmt.Println(*x)
646     }
647
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:
652
653     func Fatal(msg string) {
654         Log(msg, levelFatal)
655         panic("unreachable")
656     }
657
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
660 popular package.`,
661                 Since: "2020.1",
662         },
663
664         "SA6000": {
665                 Title: `Using regexp.Match or related in a loop, should use regexp.Compile`,
666                 Since: "2017.1",
667         },
668
669         "SA6001": {
670                 Title: `Missing an optimization opportunity when indexing maps by byte slices`,
671
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
674 strings.
675
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
681
682     k := string(b)
683     println(m[k])
684     println(m[k])
685
686 will be less efficient than
687
688     println(m[string(b)])
689     println(m[string(b)])
690
691 because the first version needs to copy and allocate, while the second
692 one does not.
693
694 For some history on this optimization, check out commit
695 f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.`,
696                 Since: "2017.1",
697         },
698
699         "SA6002": {
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.
703
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.
710
711 See the comments on https://go-review.googlesource.com/c/go/+/24371
712 that discuss this problem.`,
713                 Since: "2017.1",
714         },
715
716         "SA6003": {
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,
721
722     for _, r := range s {}
723
724 and
725
726     for _, r := range []rune(s) {}
727
728 will yield the same values. The first version, however, will be faster
729 and avoid unnecessary memory allocations.
730
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.`,
735                 Since: "2017.1",
736         },
737
738         "SA6005": {
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
741
742     if strings.ToLower(s1) == strings.ToLower(s2) {
743         ...
744     }
745
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.
749
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
755 been found.
756
757 For a more in-depth explanation of this issue, see
758 https://blog.digitalocean.com/how-to-efficiently-compare-strings-in-go/`,
759                 Since: "2019.2",
760         },
761
762         "SA9001": {
763                 Title: `Defers in range loops may not run when you expect them to`,
764                 Since: "2017.1",
765         },
766
767         "SA9002": {
768                 Title: `Using a non-octal os.FileMode that looks like it was meant to be in octal.`,
769                 Since: "2017.1",
770         },
771
772         "SA9003": {
773                 Title: `Empty body in an if or else branch`,
774                 Since: "2017.1",
775         },
776
777         "SA9004": {
778                 Title: `Only the first constant has an explicit type`,
779
780                 Text: `In a constant declaration such as the following:
781
782     const (
783         First byte = 1
784         Second     = 2
785     )
786
787 the constant Second does not have the same type as the constant First.
788 This construct shouldn't be confused with
789
790     const (
791         First byte = iota
792         Second
793     )
794
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.
797
798 When declaring enumerations with explicit values it is therefore
799 important not to write
800
801     const (
802           EnumFirst EnumType = 1
803           EnumSecond         = 2
804           EnumThird          = 3
805     )
806
807 This discrepancy in types can cause various confusing behaviors and
808 bugs.
809
810
811 Wrong type in variable declarations
812
813 The most obvious issue with such incorrect enumerations expresses
814 itself as a compile error:
815
816     package pkg
817
818     const (
819         EnumFirst  uint8 = 1
820         EnumSecond       = 2
821     )
822
823     func fn(useFirst bool) {
824         x := EnumSecond
825         if useFirst {
826             x = EnumFirst
827         }
828     }
829
830 fails to compile with
831
832     ./const.go:11:5: cannot use EnumFirst (type uint8) as type int in assignment
833
834
835 Losing method sets
836
837 A more subtle issue occurs with types that have methods and optional
838 interfaces. Consider the following:
839
840     package main
841
842     import "fmt"
843
844     type Enum int
845
846     func (e Enum) String() string {
847         return "an enum"
848     }
849
850     const (
851         EnumFirst  Enum = 1
852         EnumSecond      = 2
853     )
854
855     func main() {
856         fmt.Println(EnumFirst)
857         fmt.Println(EnumSecond)
858     }
859
860 This code will output
861
862     an enum
863     2
864
865 as EnumSecond has no explicit type, and thus defaults to int.`,
866                 Since: "2019.1",
867         },
868
869         "SA9005": {
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.
874
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.`,
878                 Since: "2019.2",
879         },
880 }