linear_never_used: a linear value was never used

A value of a linear type was bound but never consumed. Linear values must be used exactly once; letting one go out of scope silently drops it.

When the value is consumed, but only on paths that never return (an arm ending in panic), the error reads “was never used on a path that returns” and its labels point at that consumption and at the arm or branch that returns without consuming the value. Consume it on that path too. (A let? that returns early past an unconsumed value is reported separately, as linear_unconsumed_early_return.)

A program that triggers it

mod Main do
  needs IO.Console
  always_linear type Token = Token(Int)

  fn consume(t : Token) : Int do
    match t do Token(n) -> n end
  end

  fn main(_console : Cap(IO.Console)) do
    let t = Token(1)
    println("forgot the token")
  end
end

The fix

Pass the value to something that consumes it. If dropping it really is intended, the type should provide a consuming function that does so explicitly (a close, release, or similar).

mod Main do
  needs IO.Console
  always_linear type Token = Token(Int)

  fn consume(t : Token) : Int do
    match t do Token(n) -> n end
  end

  fn main(_console : Cap(IO.Console)) do
    let t = Token(1)
    println(int_to_string(consume(t)))
  end
end

Why the rule exists

Linear types model resources whose release must happen: a file handle, a session channel, a buffer that must be returned. If a linear value could be dropped on the floor, the type could not promise that its release runs.

See also: the language reference.