-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/vet: -rangeloops check only checks last statement in range loop body #21412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Related #8732. Generally, vet can only reliably prove an issue for the last statement in the loop. Using captured loop variables in earlier statements isn't provably incorrect. The closure could be executed before the end of the loop iteration. For example:
Similarly, spawned goroutines can be waited on. |
Good point, but we can do better for explicit |
Can you elaborate on which additional cases we could catch with regard to
|
I filed this for https://groups.google.com/d/msg/golang-nuts/M9Hq76csSaU/nVrpNOXyBwAJ which has examples of problems that we could catch. |
Thanks for filing this, Ian. Here's the real-world code that caused problems at my company. Once the root cause was traced to this bug, engineers responsible for this code were surprised (and slightly alarmed) that vet didn't warn them first. I've redacted or altered a few of the object names, but the idea should be clear. The code handles a batch of requests, then gathers errors for later. func (r *redactedStruct) handleBatch(ctx context.Context, batch *redactedpkg.Batch) error {
var chans []chan error
for _, request := range batch.Requests {
c := make(chan error)
go func(c chan error) {
c <- r.handle(ctx, request)
}(c)
chans = append(chans, c)
}
var err error
for _, c := range chans {
err = combineErrors(err, <-c)
}
return err
} |
Thanks for the example. So the question is whether vet can be smart enough to see that |
Duplicate of #16520 I believe. |
Running
go vet
on this file:prints
If I change F to this:
then go vet prints nothing.
Looking at the vet source code,
checkRangeLoop
only looks at the last statement of a range loop to see whether a variable is capture. This behavior dates back to when the rangeloop check was first added in https://golang.org/cl/6494075. As far as I can tell, it ought to look at every statement in the loop.The text was updated successfully, but these errors were encountered: