mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-09 15:44:33 -04:00
Add a new vet checker that rejects variables, parameters, named return values, receivers, range/type-switch bindings, type parameters, struct fields, and constants named "l" (lowercase ell) or "I" (uppercase i). Both are hard to distinguish from the digit "1" and from each other in too many fonts. Rename the two pre-existing struct fields named "l" (both of type net.Listener) in drive/driveimpl/drive_test.go to "ln", matching the convention used elsewhere for net.Listener locals. Rename the test-fixture struct fields "I" (single int label) to "Int" in metrics/multilabelmap_test.go and util/deephash/deephash_test.go, preserving the "first letters of types" convention used alongside neighboring fields like I8/I16/U/U8. Also teach pkgdoc_test.go to skip testdata/ directories, which the go tool ignores; they are not real packages. Fixes #19631 Change-Id: I71ad2fa990705f7a070406ebcdb8cefa7487d849 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package example
|
|
|
|
import "sync"
|
|
|
|
// Bad: var declarations.
|
|
var l int // want `do not use "l"`
|
|
var I int // want `do not use "I"`
|
|
|
|
// OK: variables named "ll", "II", "i" are fine.
|
|
var (
|
|
ll int
|
|
II int
|
|
i int
|
|
)
|
|
|
|
// Bad: const declaration in a function scope.
|
|
func F0() {
|
|
const l = 3 // want `do not use "l"`
|
|
const I = 4 // want `do not use "I"`
|
|
_ = l
|
|
_ = I
|
|
}
|
|
|
|
// Bad: function parameters.
|
|
func F1a(l int) {} // want `do not use "l"`
|
|
func F1b(I int) {} // want `do not use "I"`
|
|
|
|
// Bad: named return values.
|
|
func F2a() (l int) { return } // want `do not use "l"`
|
|
func F2b() (I int) { return } // want `do not use "I"`
|
|
|
|
// Bad: receiver names.
|
|
type T struct{}
|
|
|
|
func (l *T) Ml() {} // want `do not use "l"`
|
|
func (I *T) MI() {} // want `do not use "I"`
|
|
|
|
// Bad: struct fields.
|
|
type S struct {
|
|
l int // want `do not use "l"`
|
|
I int // want `do not use "I"`
|
|
}
|
|
|
|
// Bad: short variable declarations.
|
|
func F3() {
|
|
l := 1 // want `do not use "l"`
|
|
I := 2 // want `do not use "I"`
|
|
_ = l
|
|
_ = I
|
|
}
|
|
|
|
// Bad: var statement inside a function.
|
|
func F4() {
|
|
var l int // want `do not use "l"`
|
|
var I int // want `do not use "I"`
|
|
_ = l
|
|
_ = I
|
|
}
|
|
|
|
// Bad: range key/value.
|
|
func F5(xs []int) {
|
|
for l, v := range xs { // want `do not use "l"`
|
|
_ = l
|
|
_ = v
|
|
}
|
|
for _, I := range xs { // want `do not use "I"`
|
|
_ = I
|
|
}
|
|
}
|
|
|
|
// Bad: type parameters.
|
|
func F6a[l any](x l) l { return x } // want `do not use "l"`
|
|
func F6b[I any](x I) I { return x } // want `do not use "I"`
|
|
|
|
// Bad: type switch guards.
|
|
func F7(x any) {
|
|
switch l := x.(type) { // want `do not use "l"`
|
|
case int:
|
|
_ = l
|
|
}
|
|
switch I := x.(type) { // want `do not use "I"`
|
|
case int:
|
|
_ = I
|
|
}
|
|
}
|
|
|
|
// OK: clean code with no banned variables.
|
|
func F8() {
|
|
count := 0
|
|
for i := 0; i < 10; i++ {
|
|
count++
|
|
}
|
|
_ = count
|
|
}
|
|
|
|
// OK: sync.Mutex named "mu".
|
|
var mu sync.Mutex
|