Flag redundant range clauses.
diff --git a/lint.go b/lint.go
index 347209b..64e8049 100644
--- a/lint.go
+++ b/lint.go
@@ -69,6 +69,7 @@
f.lintNames()
f.lintVarDecls()
f.lintElses()
+ f.lintRanges()
return f.problems
}
@@ -577,6 +578,28 @@
})
}
+// lintRanges examines range clauses. It complains about redundant constructions.
+func (f *file) lintRanges() {
+ f.walk(func(node ast.Node) bool {
+ rs, ok := node.(*ast.RangeStmt)
+ if !ok {
+ return true
+ }
+ if rs.Value == nil {
+ // for x = range m { ... }
+ return true // single var form
+ }
+ if !isIdent(rs.Value, "_") {
+ // for ?, y = range m { ... }
+ return true
+ }
+
+ f.errorf(rs.Value, 1, "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok)
+
+ return true
+ })
+}
+
func receiverName(fn *ast.FuncDecl) string {
switch e := fn.Recv.List[0].Type.(type) {
case *ast.Ident:
diff --git a/testdata/range.go b/testdata/range.go
new file mode 100644
index 0000000..e8629ed
--- /dev/null
+++ b/testdata/range.go
@@ -0,0 +1,27 @@
+// Test for range construction.
+
+// Package foo ...
+package foo
+
+func f() {
+ // with :=
+ for x, _ := range m { // MATCH /should omit 2nd value.*range.*equivalent.*for x := range/
+ }
+ // with =
+ for y, _ = range m { // MATCH /should omit 2nd value.*range.*equivalent.*for y = range/
+ }
+
+ // all OK:
+ for x := range m {
+ }
+ for x, y := range m {
+ }
+ for _, y := range m {
+ }
+ for x = range m {
+ }
+ for x, y = range m {
+ }
+ for _, y = range m {
+ }
+}