let a = call().field lowers as a borrow of the temporary’s field; the next owned use fails in rustcOpen and answer this issue on GitHub.
ready · opened 2026-10-31 · updated 2026-10-31 · 1 comment
Found by b15 (docs/briefs/bugs/b15-1060-trusted-map-name-collision.md.report.md).
A let bound to a field of a call’s result lowers as a borrow of the temporary’s field, let a = &call().field;, where the field should be moved out. The checker passes it; rustc refuses the next owned use.
target/fast/nikaia, nikaia run)use std::process
fn main() throws {
let a = process::run("echo", ["a"]).stdout
let both = a + "\n"
print(both)
}
Lowered: let a = &process::run(..).await?.stdout;. rustc: &String: nikaia_std::concat::Plus<_> not satisfied. Expected output a and two newlines.
The let-binding’s lent-or-owned choice for a field read (scripts/where.nika -- lent_reads, the checker’s let rule); a field of a temporary has no owner to borrow from, so it is owned.
let a = make().name) and say whether it shares the defect.tests/compiler/tests/let_field_of_temporary.nika + .stdout, failing on the unfixed binary.Generated by Claude Code
A second shape of the same root, found by the prover lane’s p9 (docs/briefs/prover/p9-1053-claims-in-the-figure.md.report.md), re-run by the prover architect on the 21:11 target/fast/nikaia:
use std::process
fn main() throws {
let root = process::run("echo", ["hi"]).stdout.trim().to_string()
println(f"{root}/x")
}
nikaia check passes; nikaia run fails in rustc with “temporary value dropped while borrowed”: the lowering drops .to_string() and writes let root = process::run(..).await?.stdout.trim();. The same without .to_string(). ADR-278 D19 says a temporary is taken, so a view of a temporary’s field in a let must own (or the .to_string() kept). Add it as a second row of step 3’s test (let_view_of_temporary.nika).
Generated by Claude Code