Skip to content

x/tools/go/ssa: goto to labeled range-over-func is lowered as continue #80860

Description

@cpunion

Go version

go version go1.26.5 darwin/arm64

Also reproduced with golang.org/x/tools master at a5c4651b8e4951086fc536519d0eb869feefa7cb and with x/tools v0.38.0.

Output of go env

GOOS=darwin GOARCH=arm64

What did you do?

Built and interpreted this program with go/ssa:

package main

import "fmt"

func seq(yield func(int) bool) {
	for i := 1; i <= 4; i++ {
		if !yield(i) {
			return
		}
	}
}

func main() {
	var got []int
	restarts := 0

again:
	for i := range seq {
		got = append(got, i)
		if i == 1 && restarts < 2 {
			restarts++
			goto again
		}
	}
	fmt.Println(got)
}

The standard Go compiler prints the expected result. An equivalent go/ssa/interp test on current x/tools master prints the incorrect result.

What did you expect to see?

[1 1 1 2 3 4]

A goto to the label on a range-over-func statement must stop the current iterator call and restart the labeled range statement.

What did you see instead?

[1 2 3 4]

buildYieldFunc currently maps both _goto and _continue for the range label to yield-continue. Thus the goto is lowered like continue: the current iterator keeps yielding instead of returning false and resuming at the range label in the parent function.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.ToolsThis label describes issues relating to any tools in the x/tools repository.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions