match Over a Place Lends What an Arm Only ReadsStatus: Superseded by ADR-291 — its D1-D3 are D22-D24 there
Date: September 27, 2026
Target Version: Nikaia 0.0.229
Answers: #168, a match that binds a field of a name moves
the name
Related: Part I 6.5 (a reader takes a view), ADR-094 D2 (what
keeps a value is given it, and a copy is the program’s to write),
ADR-214 D2 (what is handed over, and the part of a whole),
ADR-137 (patterns)
match s { Shape::Named(n) => println(f"{n}") } lowered to a Rust match that
binds n by value, which takes the String out of s. A second read of s —
another match, a print, a hand-over — was rustc’s use of moved value, and
in a catch, match error { … } followed by {error} was borrow of
partially moved value: a correct program refused in a file nobody wrote.
The checker could not have said otherwise: a pattern’s bindings were all typed
unknown, so it knew neither that n is text nor what the arm does with it.
A name, or a field of one, that is not itself a view: a positional variant’s
parts in order, a variant with named fields by name, a library’s variants from
its ledger entry. A temporary is gone after the match anyway, and a view’s
parts are views already, so neither changes. A binding the variant does not
type — a nested pattern, an or-pattern — stays as it was.
It is written ref n below, which leaves the scrutinee whole. The arm
keeps a part — and it is taken, as before — where it:
push, a field, a rename, a
callee whose keeps says so (what ADR-214 already records);mutates, or a receiver
by value, such as drain;A number, a bool and a char are copied as they were, so an arm that
compares one with a number is unchanged.
A method on a bound part now resolves, so what it pauses, fails with and
touches is counted where it used to be unknown. One std test probed a
grammar action’s pause through exactly that gap; it now pauses where it says it
does.
match &s — every binding a reference, numbers included, so r > 0
compares a &i64 with an i64 and fails; the arms would need a * the
source does not write.match s.clone(): a copy the program did not
write (ADR-107 D3).