Skip to content

all: use range-over-int in counting loops - #503

Merged
hajimehoshi merged 1 commit into
ebitengine:mainfrom
hajimehoshi:claude/for-range-loop-modernization-1d7203
Aug 29, 2026
Merged

all: use range-over-int in counting loops#503
hajimehoshi merged 1 commit into
ebitengine:mainfrom
hajimehoshi:claude/for-range-loop-modernization-1d7203

Conversation

@hajimehoshi

Copy link
Copy Markdown
Member

What issue is this addressing?

None; this is a standalone cleanup.

What type of issue is this addressing?

refactor (no behavior change)

What this PR does | solves

Go 1.22 added range over an integer. This converts the 37 three-clause
counting loops that translate directly, most of them walking reflect fields
or function arguments, and drops the index where the body never used it.

Found with go fix -rangeint ./... run across the GOOS/GOARCH matrix so the
per-architecture files were covered, then extended by hand to the cases that
analyzer skips conservatively:

  • Call limits it cannot prove invariant: NumIn, NumField, Len, NumCPU
    and numABIFields. All are pure, so evaluating them once instead of on
    every iteration does not change behavior. func.go already used this form.
  • numFields in the place closures of struct_amd64.go and
    struct_arm64.go, assigned in two branches before the loop and never
    inside it.
  • wincallback.go, which carries //go:build ignore and so is never
    analyzed. It generates the zcallback_*.s files; regenerating with the
    converted loops reproduces all eight byte for byte.

Loops a range cannot express are left as they are: the 8-byte strides in
copyStruct8ByteChunks, placeStack and addStruct; the field scan in
amd64 getStruct, whose index is read after the loop; the compound
condition in setStruct; and the one-based loops in objc that skip the
first argument, emitted separately as encId.

gofmt -s -l is clean, go vet is clean on 10 platforms and go build on
all 15 that build today, and go test ./... passes on darwin/arm64.


Authored by Claude (Claude Code), on behalf of @hajimehoshi.

Go 1.22 added range over an integer, which reads better than the
three-clause form and evaluates the limit once rather than on every
iteration. Convert the loops that translate directly, most of them
walking reflect fields or function arguments.

The calls used as limits (NumIn, NumField, Len, NumCPU, numABIFields)
are all pure, so evaluating them once does not change behavior.

Loops that a range cannot express are left as they are: the 8-byte
strides in copyStruct8ByteChunks, placeStack and addStruct, the field
scan in getStruct on amd64 whose index is read after the loop, the
compound condition in setStruct, and the one-based loops in objc that
skip the self and _cmd arguments.

wincallback.go generates the zcallback_*.s files; regenerating with
the converted loops reproduces all eight of them byte for byte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 29, 2026 09:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@TotallyGamerJet TotallyGamerJet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hajimehoshi
hajimehoshi merged commit f389379 into ebitengine:main Aug 29, 2026
25 checks passed
@hajimehoshi
hajimehoshi deleted the claude/for-range-loop-modernization-1d7203 branch August 29, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants