golint: suggest `for range` when possible

for _ = range and for _, _ = range can be written as
for range instead.

Change-Id: I6d5e7aecce941260f4a4de294685f99d9ff48c09
GitHub-Last-Rev: 318343fa69fea5d2e580eabddefe6ef31802f79e
GitHub-Pull-Request: golang/lint#196
Reviewed-on: https://go-review.googlesource.com/96176
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/lint.go b/lint.go
index 946936e..cc6fef2 100644
--- a/lint.go
+++ b/lint.go
@@ -1084,20 +1084,25 @@
 		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 { ... }
+
+		if isIdent(rs.Key, "_") && (rs.Value == nil || isIdent(rs.Value, "_")) {
+			p := f.errorf(rs.Key, 1, category("range-loop"), "should omit values from range; this loop is equivalent to `for range ...`")
+
+			newRS := *rs // shallow copy
+			newRS.Value = nil
+			newRS.Key = nil
+			p.ReplacementLine = f.firstLineOf(&newRS, rs)
+
 			return true
 		}
 
-		p := f.errorf(rs.Value, 1, category("range-loop"), "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok)
+		if isIdent(rs.Value, "_") {
+			p := f.errorf(rs.Value, 1, category("range-loop"), "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok)
 
-		newRS := *rs // shallow copy
-		newRS.Value = nil
-		p.ReplacementLine = f.firstLineOf(&newRS, rs)
+			newRS := *rs // shallow copy
+			newRS.Value = nil
+			p.ReplacementLine = f.firstLineOf(&newRS, rs)
+		}
 
 		return true
 	})
diff --git a/testdata/range.go b/testdata/range.go
index af36a82..1a6725e 100644
--- a/testdata/range.go
+++ b/testdata/range.go
@@ -16,6 +16,12 @@
 	for y, _ = range m { // MATCH /should omit 2nd value.*range.*equivalent.*for y = range/
 	}
 
+	for _ = range m { // MATCH /should omit values.*range.*equivalent.*for range/
+	}
+
+	for _, _ = range m { // MATCH /should omit values.*range.*equivalent.*for range/
+	}
+
 	// all OK:
 	for x := range m {
 		_ = x