Issue #1074: Tools lowering: opt ?? other with opt: ref T?, other: ref T writes index::or(opt, || other.into()), which rustc refuses

Open and answer this issue on GitHub.

ready · opened 2026-10-31 · updated 2026-10-31 · 0 comments


agent: builder model: opus max_turns: 80 budget_usd: 16 — Found by the prover lane’s p6 (#1053 step 4, commit 28acd94), which wrote the file’s ?? return idiom instead and so carries no workaround in the tree.

Problem

In a tools/*.nika file, opt ?? other where opt: ref T? and other: ref T, T a struct of the package (here ast::Block), lowers to

nikaia_std::index::or(else_branch, || then_branch.into())

and rustc refuses it (&Block: Into<Block> / the value-vs-view mismatch). The same form in a user program (size(a ?? b), a: ref B?, b: ref B) builds and runs, so the fault is in a path the package lowering takes: the checker types the ?? as a value of the package’s Copy-like type (check_core_ops.nika ~:884, a_package_copy / a_value_written_out) or does not record it in lent_coalesces, and the emitter’s default branch (emit_core_flow.nika ~:833, index::or( + .into()) then writes a view where a value is wanted.

Probe (in a clone, not the shared checkout)

In crates/nikaia-std/src/tools/bounds_walk.nika (or any tools file that sees ast::Block) add

fn probe_either(else_branch: ref Block?, then_branch: ref Block) -> i64 sync {
    let present = else_branch ?? then_branch
    return present.stmts.len() as i64
}

then target/fast/nikaia lower-std and cargo check --profile fast -p nikaia-std --features compiler --message-format short: rustc refuses the index::or(..., || then_branch.into()) line. Suspected location (medium confidence): the ?? typing in check_core_ops.nika (both sides views of the same type: the answer is a view, the node belongs in lent_coalesces), not the emitter.

To build

  1. A ?? whose two sides are views of the same type (ref T? and ref T) is a view, lowered index::or(opt.as_ref(), || &other) or any lowering rustc accepts, in the package as in a program. Test: tests/compiler/tests/coalesce_two_views_of_a_struct.nika + .stdout (a program; the tools path is covered by step 2).
  2. The probe above lowers and compiles in a tools file; put the form into one real use (the site p6 avoided in bounds_walk.nika, let present = else_branch ?? then_branch, if its file is not in another lane’s batch), re-lower, cargo check ... --features compiler clean.

Generated by Claude Code

Back to Open Issues