ADR-354: An Element or a Field Read off a Place Is a View Where a ref T Is Declared, and a Word Is Not

Status: Accepted Date: October 14, 2026 Answers: whether given[0], over a given: ref Vec[Expr], may be bound as a ref Expr Related: ADR-094 D4 (a let over a place is a view of it); ADR-279 D8 (a word by its kind is copied at a read, every other type is lent, at every size), D10 (a borrowed left side beside a jump is a view); ADR-302 D5 (a view at the C boundary); Part I 2.2, 6.5; Part III C.1 (NK1103, NK1257)

1. Question

A let over a place is already a view of it (ADR-094 D4): let y = given[0] lends the element. Written with its type, let y: ref Expr = given[0], the same read was refused with NK1103, this value is Expr, and so was the same read as one arm of let x: ref Expr? = if c { tail } else { given[0] }. The read was typed as the element itself, and a fit compares the view flag strictly. The written type says what the untyped let already does.

2. How others do it

Rust writes the borrow, &given[0], and a &T slot takes it. C++ binds a const T& to an element without a mark. Swift and Kotlin have no view type to write. None of them copies a large value because a reference was declared.

3. Decisions

D1 — An index or a field read off a place is a view where the slot declares ref T or ref T?, and T is not a word.

Changed by ADR-views-3 D5: an index or a field read off a place is a view by inference; no slot declares ref T.

let y: ref Expr = given[0] and an arm given[0] under ref Expr? are views of the element, lowered with &. A view kept past the loan is refused as any view is (ADR-279 D11).

D2 — ref on a word by its kind is refused at every position outside the C boundary: NK1257.

Changed by ADR-views-3 D4: ref is refused everywhere outside the C boundary, so NK1257 retires when that is built.

A number (i8…i128, u8…u128, isize, usize, f32, f64), a bool, a scalar and an enum whose variants hold nothing are copied at a read (ADR-279 D8): the copy is never dearer than a pointer, so ref on one declares a view that buys nothing. It is refused on a let, a parameter, a field and a result alike, and inside their types: Vec[ref i64] declares views a walk over numbers never makes, since that walk yields the numbers (ADR-231 D1). At a let the help writes it without the type: an i64 is copied at a read; write let y = given[0]; elsewhere it writes the type without ref. A parameter the function changes is mut name: T (ADR-094 D3).

In an extern "C" declaration, ref T and ref mut T on a word are the pointer C expects (const int32_t *, int32_t *, an out-parameter such as int *len), live for the call, and are not a raw pointer (ADR-302 D5, D9); there they stay, and NK1257 does not apply.

Rejected: a warning first, as for ref String (ADR-282 D2). The few places that put ref on a word outside a let are parameters over an enum of bare variants in tools/*.nika, migrated in the same change; there is no outside program to give time. ADR-279 D8 stands.

D3 — Inside generic code a ref T is accepted, whatever T becomes.

A body over T cannot know that T will be a word; the read is lent there, and where T turns out to be i64 it is a view of a number, which is still correct.

4. Rejected

This site is open source. Improve this page.