agent: builder model: sonnet max_turns: 90 budget_usd: 15 —

Brief: #655 step 4b, an operator on a type that has none is NK1191

Score: bugs lane: S=3 (the checker passes programs only rustc refuses), O=small, C~3 M, area checker (tools/check_arith.nika, tools/check_core_expr.nika; not the parser, which the brief before this one changed).

Issue text (#655, item 3 second half, step 4)

!5, !"x", -"x" and "a" - 1 pass the checker; only rustc refuses them. To build 4: an operator on a type it does not take is refused by the checker; use an existing code if one fits.

Correction and decision (architect)

!5 is right: ! on an integer flips its bits (ADR-285 D3); it stays. The code is the existing NK1191 (arithmetic on something that has none), widened; no new code. Probes (architect, 252bcf2, all print Checked t.nika today): let a = !"x", let a = -"x", let a = -true, let a = "a" - 1, let a = "a" * 2, let a = true - 1, let a = "a" + 1. Wanted: each NK1191. Not in this step: 1 < "x" (a comparison), left for #655. Replace the NK1191 row’s sentence in docs/specification/30-nikaia-tooling.md (grep NK1191\`) with, verbatim:

NK1191 an arithmetic operator, or its compound assignment, on something that has none: text or a bool ("a" - 1, true + 1; + joins two texts and nothing else), a list, a map or a set (Part I 4.5), or a struct or an enum this unit declares - there is no overloading and no trait that gives a type an operator. The same code refuses - on anything but a number and ! on anything but a bool, an integer, a vector or a mask.

An interrupted earlier run (architect, 7280a0b)

The main checkout holds this brief’s uncommitted work from a run that ended without a report: check_arith.nika, check_core_expr.nika, check_core_ops.nika, check_core_stmt.nika (+ their lowered/*.rs, lowered.rs), the NK1191 row in 30-nikaia-tooling.md, and the four tests below. These files are yours: read git diff first, keep what is right, finish, and commit them with the rest.

Locations

To build

  1. The checks and the spec row above.
  2. Tests in tests/compiler/tests/: an_operator_on_text_is_refused.nika + .stderr ("a" - 1), a_minus_on_a_bool_is_refused.nika + .stderr (-true), a_bang_on_text_is_refused.nika + .stderr (!"x"), a_bang_on_an_integer_flips_its_bits.nika + .stdout (!5 prints -6). Run: cargo test --profile fast -p nikaia --test it -- operator arith, target/fast/nikaia test --both-settings --project tests/compiler. Commit Part of #655. Changelog: NK1191 also refuses arithmetic on text and bool, - on a non-number and ! on a non-bool non-integer.

Rules (CLAUDE.md; this block is pasted into every brief, also a fix-forward)

Report (at most 15 lines, to exactly /home/user/Nikaia/docs/briefs/b655-operator-types.md.report.md)

Fields of docs/architect.md, Briefs and reports: Result: done|noop|partial|blocked (the bare word first; Owner: is a question for the owner or none, never a role), Files, Commit, Fixes, Pushed, Tests, Gate (green|red), Deviation, Found, Needs, Changelog, Owner, Disk freed. none where nothing, and then the bare word: Deviation: none (a note) cuts the batch (batch.nika compares exactly); a note goes into the commit message. Found: is only for a defect outside your change (it cuts the batch); how you solved your own step goes into the commit message. Deviation: is only a step of the brief built otherwise than written or not built; how you verified (e.g. a test not run against the unfixed compiler) goes under Tests:. A noop says why under Tests: (what was probed), not under Deviation:. Final answer, one line: done <sha>, report <path> (or BLOCKED: ... / PUSH REJECTED ...).

Attribution: Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com Claude-Session: https://claude.ai/code/session_01GFeMqxRbtUMiGVyDMxsvEq

This site is open source. Improve this page.