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.
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 &.contains_key / get argument that is already a reference. Add a Nikaia test in tests/compiler/tests/.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