?. View Out of a Temporary Is Held for the Rest of the BlockStatus: Superseded by ADR-278 — its D1-D2 are D21-D22 there
Date: September 26, 2026
Target Version: Nikaia 0.0.211
Answers: #192, a ?. whose receiver is a temporary still
takes it, with ADR-191 D3’s what it needs is a lowering and
not a state
Refines: ADR-113 D1 (?. takes nothing), for the one shape
ADR-189 and ADR-191 left
Related: ADR-185 D2 (a binding written for the language
below), ADR-107 D3 (nothing inserted that copies)
#192 described the temporary shape as one that takes its receiver, which
is harmless: a temporary has no next line. Probing found every shape that
takes compiling and running - find(1)?.name, find(1)?.home?.x,
find(1)?.tags?.len() - and one that did not:
impl User { fn label(ref self) -> ref String { return self.name } }
let a = find(1)?.label() ?? "none" // rustc: temporary value dropped while borrowed
A reached method that hands back a view hands back a view of the User
find(1) made, and that value ends at the ;. Part III C.1.
Where the checker finds a lent ?. method reach whose result is a view and
whose receiver is rooted in a call, the emitter writes the receiver into a
binding of its own on the line before the statement and the reach reads it:
let __nikaia_held_0 = find(1);
let a = nikaia_std::index::or(match __nikaia_held_0.as_ref() { … }, || "none");
The value lives to the end of the block, as a name the program bound would. Nothing is copied, and nothing runs that did not run: the call ran first in that statement anyway.
Not on the lazy side of ??, && or ||, where it may not run at all; not
in a match arm; not after another call in the same statement, which it
would overtake; and not where the view is the block’s value or the
function’s result, which would outlive the binding. There the program is
refused in this language’s words, naming the let the program can write.
That is ADR-191 D3’s deciding where a hoist is safe, answered by where the
call would have run.
A hold on the lazy side, which would need the binding filled only when that side runs; the refusal names the one-line way out.
All of it, in 0.0.211: Checked::held_reaches, Emitter::hold_temporaries
and Emitter::held_in. crates/nikaia/tests/nullable.rs runs the program
from §1 with a view held for a let and one kept past it, and holds the
refusal on the lazy side of ??.