<< Back to previous view

[CLJ-2468] [spec] NPE when using Var with spec/conform Created: 16/Jan/19  Updated: 16/Jan/19  Resolved: 16/Jan/19

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.10
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Greg Chapman Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: spec

Attachments: Text File fn-sym-NPE-2.patch     Text File fn-sym-NPE.patch    
Patch: Code

 Description   

Example:

user=> (declare myint?)
#'user/myint?
user=> (defn myconformer [thing] (s/conform #'myint? thing))
#'user/myconformer
user=> (defn myint? [thing] (int? thing))
#'user/myint?
user=> (myconformer 1)
Execution error (NullPointerException) at java.util.regex.Matcher/getTextLength (Matcher.java:1770).

Looking at the code, I believe using a Var in this way will end up invoking the Object implementation for
specize* . Since a Var is an ifn?, fn-sym will be called with the Var as the argument. However, fn-sym
appears to expect only something which is an fn? – the regex match will fail, binding nil to f-ns and f-n,
and then demunge will cause the NPE.

I suggest the test in specize* for Object be changed to fn? (see attached patch).



 Comments   
Comment by Greg Chapman [ 16/Jan/19 5:53 PM ]

It occurred to me later that, if fn? is the correct test, we don't have to screen out maps. So here is a patch which only checks fn? before calling fn-sym.

Comment by Alex Miller [ 16/Jan/19 9:57 PM ]

In the next version of spec, specize doesn't exist anymore and a var is not going to be a valid thing to pass to conform (I'd say it's only marginally so in spec 1, certainly outside what was envisioned). So since it's not going to be valid in the future, I'm going to decline this ticket.





[CLJ-2467] ^:const no-field record reports generic class Created: 15/Jan/19  Updated: 16/Jan/19

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: Release 1.10
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Maarten Truyens Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: compiler

Approval: Triaged

 Description   

Example:

(defrecord ABC [some-field])
(def ^:const abc (->ABC :some-value))
(println (class abc))

(defrecord XYZ [])
(def ^:const xyz (->XYZ))
(println (class xyz))

results in

"sx.clj.temp.ABC
clojure.lang.PersistentArrayMap"

The XYZ seems to lose its class information, and is apparently stored as a simple map, instead of a record. I could not find the official specification of ^:const, but this behaviour seems incorrect to me, or at least inconsistent.



 Comments   
Comment by Alex Miller [ 16/Jan/19 11:20 PM ]

Possibly related: CLJ-1093, CLJ-1575, CLJ-1460





Generated at Thu Jan 17 16:10:57 CST 2019 using JIRA 4.4#649-r158309.