Issue #1081: let a = call().field lowers as a borrow of the temporary’s field; the next owned use fails in rustc

Open 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).

Problem

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.

Probe (checked on 18:40’s 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.

Location (not traced)

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.

To build

  1. Reproduce; probe the same with a user function returning a struct (let a = make().name) and say whether it shares the defect.
  2. A field read off a temporary binds owned (moved out); any lowering rustc accepts.
  3. Test tests/compiler/tests/let_field_of_temporary.nika + .stdout, failing on the unfixed binary.

Generated by Claude Code

Comments

keywan-ghadami, 2026-10-31

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

Back to Open Issues