core.typed

assoc derives imprecise type when optional attributes present

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

"Real world" use case, removing the optional forename makes things work as expected:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(def-alias TUser (HMap :mandatory {:group String}
                       :optional {:forename String}
                  ))
(def-alias TAdmin (HMap :mandatory {:group (Value "admin")}
                        :optional {:forename String}
                  ))

(ann my-user TUser)
(def my-user {:group "whee"})

(ann my-admin TAdmin)
(def my-admin (assoc my-user :group "admin"))

Smaller test case:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(cf (assoc
      (ann-form {} (HMap :optional {:a Any}))
      :b "v")
    (HMap :mandatory {:b (Value "v")} :optional {:a Any}))

Activity

Hide
Chris Spencer added a comment -

I had a quick stab at this, just to try and learn the code a bit:
https://github.com/c-spencer/core.typed/commit/c675662004b03241df596978d897cb254973bd63

Just runs the original inner update over the union. I moved the inner part out to a supporting function just to make things clearer for myself..

Passes some cursory checks, and I added a couple of simple test cases in the following commit.

user=> (cf (assoc (ann-form {} (HMap :optional {:a Any})) :b "v"))
[(U (HMap :mandatory {:b (Value "v"), :a Any}) (HMap :mandatory {:b (Value "v")} :absent-keys #{:a})) {:then tt, :else ff}]
user=> (cf (assoc (ann-form {} (HMap :optional {:b Any})) :b "v"))
[(HMap :mandatory {:b (Value "v")}) {:then tt, :else ff}]
Show
Chris Spencer added a comment - I had a quick stab at this, just to try and learn the code a bit: https://github.com/c-spencer/core.typed/commit/c675662004b03241df596978d897cb254973bd63 Just runs the original inner update over the union. I moved the inner part out to a supporting function just to make things clearer for myself.. Passes some cursory checks, and I added a couple of simple test cases in the following commit.
user=> (cf (assoc (ann-form {} (HMap :optional {:a Any})) :b "v"))
[(U (HMap :mandatory {:b (Value "v"), :a Any}) (HMap :mandatory {:b (Value "v")} :absent-keys #{:a})) {:then tt, :else ff}]
user=> (cf (assoc (ann-form {} (HMap :optional {:b Any})) :b "v"))
[(HMap :mandatory {:b (Value "v")}) {:then tt, :else ff}]
Hide
Chris Spencer added a comment -

Ah i see this in a TODO in check.clj#L2120

Show
Chris Spencer added a comment - Ah i see this in a TODO in check.clj#L2120
Hide
Chris Spencer added a comment -

s/attributes/keys

Show
Chris Spencer added a comment - s/attributes/keys

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: