Skip to content

Another bug in type inference #136

Description

@tjcampanella

In this code, the type checker does not realize that calling (every? string? [v1 v2 v3]) is equivalent to (and (string? v1) (string? v2) (string v3)) when using it as a guard to ensure v1, v2, and v3 are all strings. This is probably related to the other type inference bug in #135.

(t/ann prepare-execute-one! [t/Str (t/HVec [(t/U t/Str t/Int) :*])) :-> (t/Option (t/Map t/Kw t/Any))])

(t/defalias Vars (t/HMap :mandatory {:v1 t/Str
                                     :v2 t/Str
                                     :v3 t/Str
                                     :v4 t/Str
                                     :v5 t/Str}
                           :complete? true))
(t/ann get-vars [:-> Vars])
(defn get-vars []
  (let [res (prepare-execute-one!
             "SELECT v1, v2, v3, v4, v5 FROM vars" [])
        v1 (t/tc-ignore (:v1 res))
        v2 (t/tc-ignore (:v2 res))
        v4 (t/tc-ignore (:v3 res))
        v4 (t/tc-ignore (:v4 res))
        v5 (t/tc-ignore (:v5 res))]
    (if (every? string? [v1 v2 v3 v4 v5])
      {:v1 v1
       :v2 v2
       :v3 v3
       :v4 v4
       :v5 v5}
      (throw ...))))

Instead the type checker gives the errors below.

Type mismatch:

Expected:       t/Str

Actual:         t/Any


in:
v1

Type mismatch:

Expected:       t/Str

Actual:         t/Any


in:
v2 

and so on ...

However calling string? on each variable explicitly like this does type check.

(defn get-vars []
  (let [res (prepare-execute-one!
             "SELECT v1, v2, v3, v4, v5 FROM vars" [])
        v1 (t/tc-ignore (:v1 res))
        v2 (t/tc-ignore (:v2 res))
        v4 (t/tc-ignore (:v3 res))
        v4 (t/tc-ignore (:v4 res))
        v5 (t/tc-ignore (:v5 res))]
    (if (and (string? v1) (string? v2) (string? v3) (string? v4) (string? v5))
      {:v1 v1
       :v2 v2
       :v3 v3
       :v4 v4
       :v5 v5}
      (throw ...))))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions