Issue #1073: Lowering: a kept-buffer local handed to BTreeMap.contains_key gets one & too many (E0277 String: Borrow<&String>)

Open and answer this issue on GitHub.

bug, ready · opened 2026-10-31 · updated 2026-10-31 · 1 comment

Found by the builder of #1019 step 1 (06e4e63, report docs/briefs/tools/j1-1019-rule-type-parameters.md.report.md, Found: (1)).

In a tools/*.nika file, a local that keeps a buffer (put_viewed), handed to BTreeMap.contains_key, was lowered with one & too many. A struct field nearby was lowered to &str. rustc then refuses it: E0277 the trait Borrow<&String> is not implemented for String. The builder changed the design instead: GrammarTypesCall now carries Symbols, which is cleaner in its own right. So the defect is still in the lowering. No small probe outside tools has reproduced it yet.

To build

  1. A probe: a struct with a String field, a kept-buffer local read from it, and map.contains_key(local) on a BTreeMap[String, _]. Lower it with lower-std (or nikaia build) and confirm the extra &.
  2. Fix the borrow count in the lowering of a contains_key / get argument that is already a reference. Add a Nikaia test in tests/compiler/tests/.

Comments

keywan-ghadami, 2026-10-31

Another instance, met by the tools lane (j4, 20a79c9, members[S]), on BTreeMap.get rather than contains_key:

In crates/nikaia-std/src/tools/grammar_types.nika grammar_types_members (532), writing

let name = f"{words.resolve(built.name)}"
let declared = work.structs.get(name)?.clone()   // work.structs: collections::BTreeMap[String, (..)]

keeps name in a tether Keep frame and lowers to .get(&name) with name: &String: rustc E0277 String: Borrow<&String>. The builder passed words.resolve(built.name) directly instead (line 534 today), as grammar_types_put does. Reproduce: put the two lines back and run lower-std. A ten-line user program of the same shape (let name = f"{word(i)}", then work.structs.get(name)?.clone() over a ref Work) lowers and runs fine on 20a79c9, so the trigger is the Keep frame, not the call. The fix should cover every map method taking a key (get, contains_key, remove, get_mut).


Generated by Claude Code

Back to Open Issues