fix: unary arithmetic type-error message no longer crashes the reporter

rewrite-message assumed janet's BINARY arithmetic dispatch error shape
("could not find method :+ for 1 or :r+ for "a""). Unary inc/dec/- on a
non-number produce "could not find method :+ for "x"" — no "or :r" clause
— so orpos was nil and the reporter itself threw "could not find method :+
for nil", burying the real error. Handle the unary form. Found auditing
the RFC 0006 checker's default (checker-off) path. Regression row in
cli-test.
This commit is contained in:
Yogthos 2026-06-13 12:26:56 -04:00
parent f2d65addc8
commit 37949ac602
2 changed files with 19 additions and 7 deletions

View file

@ -259,18 +259,24 @@
[msg]
(def msg (string msg))
(cond
# janet polymorphic arithmetic: could not find method :+ for 1 or :r+ for "a"
# janet polymorphic arithmetic. Binary: "could not find method :+ for 1 or
# :r+ for "a"". Unary (inc/dec/-): "could not find method :+ for "x"" — no
# "or :r" clause, so orpos is nil; handle both without crashing the reporter.
(string/has-prefix? "could not find method :" msg)
(let [rest* (string/slice msg (length "could not find method :"))
sp (string/find " " rest*)
op (string/slice rest* 0 sp)
tail (string/slice rest* (+ sp (length " for ")))
orpos (string/find " or :r" tail)
a (string/slice tail 0 orpos)
forpos (string/find " for " tail (+ orpos 1))
b (string/slice tail (+ forpos 5))]
(string "Cannot " (get op-words op op) " " a " and " b
" — " op " expects numbers"))
orpos (string/find " or :r" tail)]
(if (nil? orpos)
# unary form: one operand
(string "Cannot " (get op-words op op) " " tail
" — " op " expects numbers")
(let [a (string/slice tail 0 orpos)
forpos (string/find " for " tail (+ orpos 1))
b (string/slice tail (+ forpos 5))]
(string "Cannot " (get op-words op op) " " a " and " b
" — " op " expects numbers"))))
# janet fixed-arity: <function _r$ns/f--N> called with 2 arguments, expected 1
(and (string/has-prefix? "<function " msg) (string/find "> called with " msg))
(let [nm-end (string/find ">" msg)

View file

@ -45,6 +45,12 @@
(check "arith error message rewritten"
(run-err "-e" `(+ 1 "a")`)
(has `Cannot add 1 and "a"`))
# unary arithmetic (inc/dec) on a non-number: the host error has no "or :r"
# clause, which used to crash the rewriter itself — handle it (jolt audit)
(check "unary arith error does not crash the rewriter"
(run-err "-e" `(inc "x")`)
(fn [s] (and (string/find "expects numbers" s)
(nil? (string/find "could not find method" s)))))
(check "arity error names the fn"
(run-err "-e" "(defn afn [x] x) (afn 1 2)")
(has "Wrong number of args (2) passed to: user/afn"))