let s = path.last() ?? return null; return s.inner, passes check and fails in rustc (E0507)Open and answer this issue on GitHub.
ready, wip · opened 2026-10-31 · updated 2026-10-31 · 0 comments
agent: builder
model: opus
max_turns: 80
budget_usd: 16
—
Problem. A field that does not copy, read off a local bound to an element read (let s = path.last() ?? return null) and handed back by value, passes nikaia check and fails in rustc (Cannot move out of s.inner which is behind a shared reference). The whole element handed back is refused since #1044 (920d8608, NK1131 with help …?.clone()); its field is not. Found by b8 (#1044) and probed by the bugs architect on the fast binary at 1e5b0a7c.
Probe
struct Inner { name: String }
struct Item { inner: Inner }
fn last_inner(path: Vec[Item]) -> Inner? {
let s = path.last() ?? return null
return s.inner
}
fn main() {
let xs = [Item { inner: Inner { name: "a" } }, Item { inner: Inner { name: "b" } }]
let r = last_inner(xs) ?? return
println(r.name)
}
Rows (same Inner/Item, body of last_inner):
s.inner and path, help Write `s.inner.clone()` for a copy.return (path.last() ?? return null).inner - rustc Cannot move out of a shared reference; want NK1131.let s = path.last() ?? return null; let x = s.inner; return x - rustc Mismatched types; untraced.b, must stay): return s.inner.clone().return s - NK1131 (#1044).Suspected location. check_core_a_lent_place_given_away, crates/nikaia-std/src/tools/check_core_leaves.nika:117, the Expr::Field arm (:158): place_path gives s.inner with root s, then !state.lent_here(root) (:226) returns, because s is a let with view_of = path.last(), not a lent parameter. The Variable arm (:126-157) already tells such a local (check_core_leaves_list_of_a_read) and refuses through check_core_leaves_an_element_read_given_away.
To build
let s = m.get(k) ?? return null; return s.inner): in the Field arm, when the root is a binding whose view_of is an element read (check_core_leaves_list_of_a_read non-null), keeps holds and the field’s type does_not_copy, refuse NK1131 through check_core_leaves_an_element_read_given_away (what = the field path, help copying the field path with .clone()). Test tests/compiler/tests/a_field_of_an_element_read_handed_back.nika + .stderr (rows a and map form), a_field_of_an_element_read_copied.nika + .stdout (row d). Bug-lane brief b10.Expr::Coalesce; see #1055’s fix for a field of a ?? result). Own brief after step 1.Rules: docs/briefs/common.part. Report: fields of docs/architect.md, Briefs and reports.
Generated by Claude Code