diff --git a/src/jolt/main.janet b/src/jolt/main.janet index af7527c..602bdff 100644 --- a/src/jolt/main.janet +++ b/src/jolt/main.janet @@ -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: called with 2 arguments, expected 1 (and (string/has-prefix? " called with " msg)) (let [nm-end (string/find ">" msg) diff --git a/test/integration/cli-test.janet b/test/integration/cli-test.janet index eef40aa..8b490f6 100644 --- a/test/integration/cli-test.janet +++ b/test/integration/cli-test.janet @@ -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"))