We're updating the issue view to help you get more done. 

Fix confusing macroexpand1 ArityException handling

Description

macros can give very confusing error messages when they execute a form which generates an ArityException. clojure.lang.Compiler.macroexpand1 assumes that any ArityException comes from the call to the macro itself, which need not be the case. For instance:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 user> (do (defmacro f [] (assoc)) (f)) ArityException Wrong number of args (-2) passed to: core$assoc clojure.lang.Compiler.macroexpand1 (Compiler.java:6488) user> (use 'clojure.repl) (pst) nil ArityException Wrong number of args (-2) passed to: core$assoc clojure.lang.Compiler.macroexpand1 (Compiler.java:6488) clojure.lang.Compiler.macroexpand (Compiler.java:6544) clojure.lang.Compiler.eval (Compiler.java:6618) clojure.lang.Compiler.eval (Compiler.java:6624) clojure.lang.Compiler.eval (Compiler.java:6597) clojure.core/eval (core.clj:2864) clojure.main/repl/read-eval-print--6596/fn--6599 (main.clj:260) clojure.main/repl/read-eval-print--6596 (main.clj:260) clojure.main/repl/fn--6605 (main.clj:278) clojure.main/repl (main.clj:278) clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn--1251 (interruptible_eval.clj:56) clojure.core/apply (core.clj:617) nil

Easy enough to see the source of the problem in this case, but because both the number of arguments actually passed is off by two, and the stacktrace element for the call to assoc has been dropped, this shortcut by macroexpand1 can get super confusing.

Proposed: Store full class name in ArityException, demunge in exception string (so no change there), then munge the macro being expanded and compare to the munged class name in ArityException. If the same, then the arity problem is in the macro, otherwise from some function inside the macro.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 user=> (do (defmacro f [] (assoc)) (f)) ArityException Wrong number of args (0) passed to: core$assoc clojure.lang.AFn.throwArity (AFn.java:437) user=> (use 'clojure.repl) (pst) nil ArityException Wrong number of args (0) passed to: core$assoc user/f (NO_SOURCE_FILE:1) clojure.lang.Var.invoke (Var.java:419) clojure.lang.Var.applyTo (Var.java:532) clojure.lang.Compiler.macroexpand1 (Compiler.java:6507) clojure.lang.Compiler.macroexpand (Compiler.java:6580) clojure.lang.Compiler.eval (Compiler.java:6654) clojure.lang.Compiler.eval (Compiler.java:6660) clojure.lang.Compiler.eval (Compiler.java:6633) clojure.core/eval (core.clj:2864) clojure.main/repl/read-eval-print--6594/fn--6597 (main.clj:260) clojure.main/repl/read-eval-print--6594 (main.clj:260) clojure.main/repl/fn--6603 (main.clj:278) nil

Patch: clj-1279-3.patch

Environment

None

Status

Assignee

Alex Miller

Reporter

Alex Coventry

Approval

Ok

Patch

Code and Test

Fix versions

Affects versions

Release 1.6

Priority

Major