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

Docs

XO0436: `for` over `next()` with a `?` that does not match it

error · reported by the checker

A value whose type has next() -> T? is iterated by for x in v, which calls next until it returns None. When next returns T? ! E, each step can fail, and the loop must say where the error goes: for x? in v propagates it as ? does. Write the ? when next can fail and leave it out when it cannot; to handle the error inside the loop, write loop { match v.next() { Ok(Some(x)) => ... Ok(None) => break Err(e) => ... } }. See core 3.5 and decision 0494.

Example

struct Pages {
  left: Int
}

fn (var p: Pages) next() -> Int? ! Str {
  if p.left == 0 { return Ok(None) }
  p.left -= 1
  Ok(Some(p.left))
}

fn total(var p: Pages) -> Int ! Str {
  var n = 0
  for x in p { n += x }
  Ok(n)
}

Fix

struct Pages {
  left: Int
}

fn (var p: Pages) next() -> Int? ! Str {
  if p.left == 0 { return Ok(None) }
  p.left -= 1
  Ok(Some(p.left))
}

fn total(var p: Pages) -> Int ! Str {
  var n = 0
  for x? in p { n += x }
  Ok(n)
}

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