[gopls-release-branch.0.18] gopls/internal/analysis/modernize: fix rangeint bug

info.Defs[v] is nil if the loop variable is not declared
(for i = 0 instead of for i := 0).

+ test

Updates golang/go#71847

Change-Id: I28f82188e813f2d4f1ddc9335f0c13bd90c31ec1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/650815
Auto-Submit: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
(cherry picked from commit 300465cc970af3836a5368d587764267a8f4d77e)
Reviewed-on: https://go-review.googlesource.com/c/tools/+/651095
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Commit-Queue: Alan Donovan <adonovan@google.com>
diff --git a/gopls/internal/analysis/modernize/rangeint.go b/gopls/internal/analysis/modernize/rangeint.go
index 2d25d6a..273c138 100644
--- a/gopls/internal/analysis/modernize/rangeint.go
+++ b/gopls/internal/analysis/modernize/rangeint.go
@@ -75,7 +75,7 @@
 						// Have: for i = 0; i < limit; i++ {}
 
 						// Find references to i within the loop body.
-						v := info.Defs[index]
+						v := info.ObjectOf(index)
 						used := false
 						for curId := range curLoop.Child(loop.Body).Preorder((*ast.Ident)(nil)) {
 							id := curId.Node().(*ast.Ident)
diff --git a/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go b/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go
index a60bd5e..6c30f18 100644
--- a/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go
+++ b/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go
@@ -12,6 +12,9 @@
 	for i := 0; i < len(slice); i++ { // want "for loop can be modernized using range over int"
 		println(slice[i])
 	}
+	for i := 0; i < len(""); i++ { // want "for loop can be modernized using range over int"
+		// NB: not simplified to range ""
+	}
 
 	// nope
 	for i := 0; i < 10; { // nope: missing increment
@@ -38,3 +41,13 @@
 }
 
 func f() int { return 0 }
+
+// Repro for part of #71847: ("for range n is invalid if the loop body contains i++"):
+func _(s string) {
+	var i int                    // (this is necessary)
+	for i = 0; i < len(s); i++ { // nope: loop body increments i
+		if true {
+			i++ // nope
+		}
+	}
+}
diff --git a/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go.golden b/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go.golden
index 348f775..52f1634 100644
--- a/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go.golden
+++ b/gopls/internal/analysis/modernize/testdata/src/rangeint/rangeint.go.golden
@@ -12,6 +12,9 @@
 	for i := range slice { // want "for loop can be modernized using range over int"
 		println(slice[i])
 	}
+	for range len("") { // want "for loop can be modernized using range over int"
+		// NB: not simplified to range ""
+	}
 
 	// nope
 	for i := 0; i < 10; { // nope: missing increment
@@ -38,3 +41,13 @@
 }
 
 func f() int { return 0 }
+
+// Repro for part of #71847: ("for range n is invalid if the loop body contains i++"):
+func _(s string) {
+	var i int                    // (this is necessary)
+	for i = 0; i < len(s); i++ { // nope: loop body increments i
+		if true {
+			i++ // nope
+		}
+	}
+}