Status: Accepted
Date: September 21, 2026
Closes: #153 (a let that declares a
type over a for binding) and #139 (a grammar entry in tail position over a
local that owns its input)
Builds on: ADR-182, which is the same sentence one construct
back — a view the compiler wrote, meeting something that had not heard
Related: ADR-094 D4 (a for lends),
ADR-283 D3 (a copy is written and never inserted),
ADR-292 D18 (ARM_VALUE, a block made a statement),
ADR-296 (whose own test put a program in the second shape)
Two more constructs beyond ADR-182’s meet a view the compiler wrote, and without a decision both are Part III C.1:
for r in rows { let copy: Row = r } // mismatched types
// consider using clone here
fn both(text: ref String) -> i64 throws {
let data = text.to_owned()
return Tiny::number(data) // `data` does not live long enough
}
Both messages tell the reader to do something the language forbids or cannot say. Consider using clone here asks for the copy ADR-283 D3 says is written and never inserted. Does not live long enough names a local whose lifetime the source never mentions.
let that declares the element’s type over a for binding is a refusal, not a lowering.NK1183. A for lends (ADR-094 D4), so the binding is a view
and an annotation naming the element is a type the value does not have.
A refusal and not a lowering, because the alternative is a copy. The
numeric half is already a lowering — ADR-182 D5 reads a number
through the view, and that inserts nothing, because a number is Copy. A
struct is not, so the same answer there would be a copy the source did not
write.
The way out is the annotation coming off, and it is one the program can
take: a view reads the same, and copy.a reaches through it. That is what
makes this C.2’s shape rather than C.1’s alone — the
compiler knew both that the annotation was wrong and what to write instead, and
said neither.
And the copy is named beside it, because sometimes it is what was meant — but it is the program’s to write.
Ok.let __nikaia_value = { … }?; Ok(__nikaia_value) in place of Ok({ … }?).
The lowering of an entry is a block holding let _source = &*data and a stream
over it. Inside Ok(…?) those temporaries live to the end of the enclosing
block, past the local that owns the text. A let makes the block a
statement, so they drop at the ; and ahead of the local — which is
ADR-292 D18’s ARM_VALUE trick one construct over, for the same
kind of reason. rustc’s own hint is this fix: save the expression’s value in
a new local variable.
Only where the lowering writes the borrow. It is the emitter’s own
_source and not something a program’s expression left behind, so the one
shape this emitter can be sure of is the one it takes. Every other tail keeps
Ok(x), because a line the generated file does not need is a line a reader has
to skip (ADR-296 D17).
let whose annotation is a view of the element. let copy: ref Row = r
is what the binding already is, and whether writing it is worth saying
anything about is a question nobody has asked.