Why this fires¶
A linear value is still owed when control leaves: at the end of its block,
when the function returns, or on the failure path of a ?. Every value of an
@linear type must be consumed exactly once on every path.
fn transfer() -> Result<int, str> {
let tx = db.begin()?
tx.execute("UPDATE ...")? // TE170: `tx` leaks if this fails
return tx.commit()
}Fix it¶
Consume it on that path: pass it to a sink parameter or a sink self
method, return it, or cover the exits once with a defer:
let tx = db.begin()?
defer_err tx.rollback() // every failure exit rolls back
tx.execute("UPDATE ...")?
return tx.commit() // success is explicitdefer_err covers only failure exits and defer_ok only successful ones;
defer covers both. A value consumed explicitly first is not consumed again
by its defer.
Reading a field does not consume: r.value only borrows r. A type with no
sink self method — and a consumer ending its own self — ends the value by
taking it apart, which the module that declares the type may do:
@linear
struct Res { value: int }
fn teste(sink r: Res) -> int {
let Res { value } = r // consumes r
return value
}