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

Docs

XO0530: binding the payload of a field shares every heap field of a large value

warning · reported by the vet

Reported by xo vet, not xo check. match s.conn { Some(c) => ... } (or if let) on a field of a value that lives on binds a copy of the payload: every reference counted field of it (Str, Bytes, List, Map, handles) is shared, and released again when the copy or the field is dropped. For a payload with at least 8 such fields that is a fixed walk on every match, which profiles of the HTTP/2 server found at about 4,000 instructions a request. Test the field with .is_none() or a pattern without bindings first when the payload is not needed, read the one part needed (s.conn.map(...)), or take the value out of its owner before matching. See decision 0263.

Example

struct Conn {
  a: Str, b: Str, c: Str, d: Str
  e: Str, f: Str, g: Str, h: Str
}

struct Srv {
  conn: Conn?
}

fn label(s: Srv) -> Str {
  match s.conn {
    Some(c) => c.a
    None => "none"
  }
}

Fix

struct Conn {
  a: Str, b: Str, c: Str, d: Str
  e: Str, f: Str, g: Str, h: Str
}

struct Srv {
  conn: Conn?
}

fn label(s: Srv) -> Str {
  if s.conn.is_none() {
    return "none"
  }
  s.conn.map(fn(c) { c.a }) ?? "none"
}

Run xo explain XO0530 for this text in a terminal, or see section 10.6 of the specification.