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

Using 'def with metadata {:type :anything} throws ClassCastException during printing

Description

Specific to setting :type meta on a var:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 user=> (def ^{:type :anything} mydef 1) #<main$repl clojure.main$repl@6193b845> CompilerException java.lang.ClassNotFoundException: main.clj:257, compiling:(NO_SOURCE_PATH:13:20) ClassCastException clojure.lang.Var cannot be cast to clojure.lang.IObj clojure.core/with-meta (core.clj:214) user=> (pst *e) ClassCastException clojure.lang.Var cannot be cast to clojure.lang.IObj clojure.core/with-meta (core.clj:214) clojure.core/vary-meta (core.clj:640) clojure.core/fn--5420 (core_print.clj:76) clojure.lang.MultiFn.invoke (MultiFn.java:232) clojure.core/pr-on (core.clj:3392) clojure.core/pr (core.clj:3404) clojure.core/apply (core.clj:624) clojure.core/prn (core.clj:3437) clojure.main/repl/read-eval-print--6627 (main.clj:241) clojure.main/repl/fn--6636 (main.clj:258) clojure.main/repl (main.clj:258) clojure.main/repl-opt (main.clj:324)

If it is intended to forbid setting the :type metadata, then there should be an appropriate error message instead of the ClassCastException.

Cause: This is caused by the printer dispatch function

1 2 3 (defmulti print-method (fn [x writer] (let [t (get (meta x) :type)] (if (keyword? t) t (class x)))))

which ends up calling the default dispatch, which tries to vary-meta.

Solution: Add a check in the default print-method for (instance? clojure.lang.IObj o) before calling vary-meta and fallback to print-simple.

Patch: CLJ-1039-tolerate-misleading-type-metadata-on-var-wh.patch

Screened by: Alex Miller

Environment

Ubuntu, lein 1.7.1 - lein repl

Status

Assignee

Unassigned

Reporter

import

Labels

Approval

Ok

Patch

Code and Test

Fix versions

Affects versions

Release 1.4

Priority

Minor