Skip to content

Commit 64804da

Browse files
madelinekalilgopherbot
authored andcommitted
go/analysis/passes/modernize: slicescontains: omit fix with empty body
In the slicescontains modernizer, if the inspected RangeStmt's child IfStmt contains an unlabeled break statement, the fix will remove it. If the IfStmt contains only the break and no other statements, the resulting fix will have a call to "if slices.Contains(...) {}" with an empty body. This code is confusing and produces a linter error, so we should avoid suggesting a fix. Fixes golang/go#77677 Change-Id: I7c0368678b9034aa698febca2acf20c0071e29c9 Reviewed-on: https://go-review.googlesource.com/c/tools/+/749160 TryBot-Bypass: Madeline Kalil <mkalil@google.com> Auto-Submit: Madeline Kalil <mkalil@google.com> Reviewed-by: Alan Donovan <adonovan@google.com>
1 parent da12812 commit 64804da

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

go/analysis/passes/modernize/slicescontains.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ func slicescontains(pass *analysis.Pass) (any, error) {
231231
// that might affected by melting down the loop.
232232
//
233233
// TODO(adonovan): relax check by analyzing branch target.
234+
numBodyStmts := 0
234235
for curBodyStmt := range curBody.Children() {
236+
numBodyStmts += 1
235237
if curBodyStmt != curLastStmt {
236238
for range curBodyStmt.Preorder((*ast.BranchStmt)(nil), (*ast.ReturnStmt)(nil)) {
237239
return
@@ -292,7 +294,16 @@ func slicescontains(pass *analysis.Pass) (any, error) {
292294
case *ast.BranchStmt:
293295
if lastStmt.Tok == token.BREAK && lastStmt.Label == nil { // unlabeled break
294296
// Have: for ... { if ... { stmts; break } }
295-
297+
if numBodyStmts == 1 {
298+
// If the only stmt in the body is an unlabeled "break" that
299+
// will get deleted in the fix, don't suggest a fix, as it
300+
// produces confusing code:
301+
// if slices.Contains(slice, f) {}
302+
// Explicitly discarding the result isn't much better:
303+
// _ = slices.Contains(slice, f) // just for effects
304+
// See https://go.dev/issue/77677.
305+
return
306+
}
296307
var prevStmt ast.Stmt // previous statement to range (if any)
297308
if curPrev, ok := curRange.PrevSibling(); ok {
298309
// If the RangeStmt's previous sibling is a Stmt,

go/analysis/passes/modernize/testdata/src/slicescontains/slicescontains.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,11 @@ func issue76210negation(haystack []string, needle string) bool {
224224
}
225225
return res
226226
}
227+
228+
func issue77677emptybody(slice []int, needle int) {
229+
for _, elem := range slice { // nope: would produce "if slices.Contains" with an empty body
230+
if elem == needle {
231+
break
232+
}
233+
}
234+
}

go/analysis/passes/modernize/testdata/src/slicescontains/slicescontains.go.golden

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,11 @@ func issue76210negation(haystack []string, needle string) bool {
166166
}
167167
return res
168168
}
169+
170+
func issue77677emptybody(slice []int, needle int) {
171+
for _, elem := range slice { // nope: would produce "if slices.Contains" with an empty body
172+
if elem == needle {
173+
break
174+
}
175+
}
176+
}

0 commit comments

Comments
 (0)