Xo is experimental. The source is now public on GitHub, or try Xo in your browser.
Menu · XO0534

Docs

XO0534: a task captures a value with many heap fields

note · reported by the vet

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.