|
1593 | 1593 | (get-in env [:locals sym]))
|
1594 | 1594 | [sym tag])))))))
|
1595 | 1595 |
|
1596 |
| -(defn- add-predicate-induced-tags |
1597 |
| - "Looks at the test and adds any tags which are induced by virtue |
1598 |
| - of the predicate being satisfied. For example in (if (string? x) x :bar) |
| 1596 | +(defn- truth-induced-tag |
| 1597 | + "Refine a tag to exclude clj-nil if the test is a simple symbol." |
| 1598 | + [env test] |
| 1599 | + (when (and (symbol? test) |
| 1600 | + (nil? (namespace test))) |
| 1601 | + (let [analyzed-symbol (no-warn (analyze (assoc env :context :expr) test))] |
| 1602 | + (when-let [tag (:tag analyzed-symbol)] |
| 1603 | + (when (and (set? tag) |
| 1604 | + (contains? tag 'clj-nil)) |
| 1605 | + [test (canonicalize-type (disj tag 'clj-nil))]))))) |
| 1606 | + |
| 1607 | +(defn- set-test-induced-tags |
| 1608 | + "Looks at the test and sets any tags which are induced by virtue |
| 1609 | + of the test being truthy. For example in (if (string? x) x :bar) |
1599 | 1610 | the local x in the then branch must be of string type."
|
1600 | 1611 | [env test]
|
1601 | 1612 | (let [[local tag] (or (simple-predicate-induced-tag env test)
|
1602 |
| - (type-check-induced-tag env test))] |
| 1613 | + (type-check-induced-tag env test) |
| 1614 | + (truth-induced-tag env test))] |
1603 | 1615 | (cond-> env
|
1604 |
| - local (update-in [:locals local :tag] (fn [prev-tag] |
1605 |
| - (if (or (nil? prev-tag) |
1606 |
| - (= 'any prev-tag)) |
1607 |
| - tag |
1608 |
| - prev-tag)))))) |
| 1616 | + local (assoc-in [:locals local :tag] tag)))) |
1609 | 1617 |
|
1610 | 1618 | (defmethod parse 'if
|
1611 | 1619 | [op env [_ test then else :as form] name _]
|
|
1614 | 1622 | (when (> (count form) 4)
|
1615 | 1623 | (throw (compile-syntax-error env "Too many arguments to if" 'if)))
|
1616 | 1624 | (let [test-expr (disallowing-recur (analyze (assoc env :context :expr) test))
|
1617 |
| - then-expr (allowing-redef (analyze (add-predicate-induced-tags env test) then)) |
| 1625 | + then-expr (allowing-redef (analyze (set-test-induced-tags env test) then)) |
1618 | 1626 | else-expr (allowing-redef (analyze env else))]
|
1619 | 1627 | {:env env :op :if :form form
|
1620 | 1628 | :test test-expr :then then-expr :else else-expr
|
|
0 commit comments