ADR-185: A View Meets Two More Constructs That Were Never Told

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)


1. Context

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.

2. Decisions

D1 — A 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.

D2 — A tail that enters a grammar binds its value before the 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).

3. Consequences

4. What this does not decide

This site is open source. Improve this page.