code: func (f *file) lintRanges() {
  	f.walk(func(node ast.Node) bool {
  		rs, ok := node.(*ast.RangeStmt)
  		if !ok {
  			return true
  		}
  
  		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
  		}
  
  		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)
  		}
  
  		return true
  	})
  }
docs: // lintRanges examines range clauses. It complains about redundant constructions.