Skip to content

don't allocate closure variables if the closure doesn't escape #4196

Open
@eliasnaur

Description

@eliasnaur

This example,

package main

import (
	"sort"
)

var slice = make([]int, 1000)

func main() {
	closedVar := 10
	closedSlice := slice[10:100]
	// The closure to sort.Find doesn't escape, so
	// neither should the variables closed over.
	sort.Find(len(closedSlice), func(i int) int {
		return closedSlice[i] - closedVar
	})
}

results in:

tinygo build -target pico -print-allocs=. closures.go
/Users/a/proj/tinygo/closures.go:11:2: object allocated on the heap: escapes at line 12
/Users/a/proj/tinygo/closures.go:10:2: object allocated on the heap: escapes at line 12
...

Since the function argument to sort.Find doesn't escape, the variables referenced in the closure shouldn't escape either.

This issue makes it hard to use closures in a GC friendly way, essentially forcing the manual inlining of sort.Find and similar functions. In future, I expect similar issues for Go iterator functions (as anticipated in Go 1.23).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions