m.entry(k).or_insert(v) hands back stays a &mut into the map, so a later use of the map is refused by rustcOpen and answer this issue on GitHub.
ready · opened 2026-11-03 · updated 2026-11-03 · 0 comments
Found while probing the forms a CDCL(T) solver needs in Nikaia: the e-graph of ADR-270 D13 keeps a signature table (hash-consing, term to id). Probed on target/fast/nikaia at 31e2ea7, language 0.0.1341.
use std::collections
fn main() {
let mut t: collections::HashMap[i64, i64] = collections::HashMap()
let id = t.entry(7).or_insert(3)
let n = t.len()
println(f"{id} {n}")
}
nikaia check accepts it; nikaia run fails in rustc: Cannot borrow t as immutable because it is also borrowed as mutable. Expected: 3 1.
id is a let without mut of a value that copies (i64), so in Nikaia it is a number of its own; the lowering keeps it as Rust’s &mut i64 into the map, and every later use of t while id lives is refused. The same with a tuple key (HashMap[(u32, u32, u32), u32]).
tests/compiler/tests/a_value_or_insert_hands_back_is_a_copy.nika with the probe and 3 1 as its .stdout.or_insert / or_insert_with is bound by a let without mut, or used as a value, and its type copies, lower it as a copy (*m.entry(k).or_insert(v)). A let mut over it stays a view of the entry (in-place change, as for let mut c = m[k] ?? continue, #816). A type that does not copy: as today, a view while read; check the case with a String value and state in the report what it does.