XO0534: a task captures a value with many heap fields
Reported by xo vet, not xo check. A closure passed to Scope.spawn or spawn_background captures by value (core 5.1): the spawn shares each heap field of the value (Str, Bytes, List, Map, Set, boxes, handles, counted through nested structs) and the task’s end releases them, and the first change to a collection in it while both the task and the spawner hold it copies that collection. For a struct the size of the compiler’s Checker that is hundreds of count updates per task. Bind the fields the task uses before the spawn and capture those. The program is correct either way; this is about time. See core 5.1 and decision 0294.
Example
// State has 40 List and Map fields
fn run(st: State) {
scope s {
s.spawn(fn() { count(st.users) })
}
}Fix
fn run(st: State) {
let users = st.users
scope s {
s.spawn(fn() { count(users) })
}
}Run xo explain XO0534 for this text in a terminal, or see
section 10.6 of the specification.