Files
tailscale/cmd/vet/lowerell/testdata/src/example/example.go
Brad Fitzpatrick 9bb7ca6116 cmd/vet/lowerell, drive/driveimpl: forbid variables named "l" or "I"
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>
2026-05-04 14:03:28 -07:00

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