<< Back to previous view

[CTYP-133] Typechecker fails when checking involves an object from reify Created: 13/Apr/14  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: 0.4.x

Type: Enhancement Priority: Minor
Reporter: Daniel Ziltener Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 4
Labels: None
Environment:

Clojure 1.6.0, core.typed 0.2.44



 Description   

The error message is

No method in multimethod 'check' for dispatch value: :reify

The following is a minimal test case which fails:

(ns core-typed-bug.core
  (:require [clojure.core.typed :refer :all]))

(ann-protocol ITypedTest
              get-data [ITypedTest -> Any])
(defprotocol> ITypedTest
  (get-data [this]))

(ann typed-test [String -> ITypedTest])
(defn typed-test [input]
  (reify ITypedTest
    (get-data [_] input)))

(defn> testfn :- Any
  [asdf :- Keyword, in :- ITypedTest]
  (get-data in))

Likely similar to bug CTYP-132.

Branch: https://github.com/clojure/core.typed/pull/28/files



 Comments   
Comment by Jochen Hinrichsen [ 25/Jul/14 4:36 AM ]

Also on clojure 1.5.1, core.typed 0.2.65

No method in multimethod 'check' for dispatch value: :reify

Comment by Donald Ball [ 21/Mar/16 8:09 PM ]

This is still present in core.typed 0.3.22, and presents my sole use of ^:no-check in one of my libraries. I use protocols like they're going out of style and lean on reify a good bit, it'd be nice to not have to dodge around it thereby.





[CTYP-297] Allow defmulti without expected type Created: 17/Nov/15  Updated: 06/Dec/17

Status: Reopened
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: 0.4.x

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

defmulti expressions need an expected type at the moment. This is annoying and we can do better.

This should type check without issues.

(defmulti f identity)

Solution

Remove the restriction on a MultiFn requiring an expected type. This raises the question of how to infer the type of a multimethod based only on its dispatch function.

Here is the new scheme:

If the dispatch function is a function type

[b ... b -> c]

the entire multimethod is of type

[b ... b -> Any]

That is, infer the type of the dispatch function, and replace the return types with Any.

eg.

(defmulti f identity)

Dispatch function is of type

(All [x] [x -> x :object {:id 0}])

Multimethod annotated as:

(All [x] [x -> Any])

Filters and objects should be deleted from the dispatch function to generate the multimethod annotation.

Pull request: 83
Commit:
Version:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 03/Dec/17 4:06 PM ]

Never completed, closing.





[CTYP-231] (Array X) is broken and undocumented Created: 23/Jun/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Marc O'Morain Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

There is no documentation about (Array X) in the API docs: http://clojure.github.io/core.typed/#clojure.core.typed - it was hard to find our that such a thing existed.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 23/Jun/15 8:26 AM ]

Unfortunately it's intentional. It's a long standing issue, one that I've thought long and hard about, but Arrays broken right now. The main problem is that there is no distinction between an array of boxed values and an array of unboxed values – you can upcast from one the other.

I will put this near the top of the list of things to do.

Comment by Marc O'Morain [ 23/Jun/15 8:39 AM ]

We have a few uses of Array in our code-base. The few I have been touching today are for annotating clojure.java.io signatures. We don't use the byte[] forms of the functions at present, so we should be OK for now.

Thanks

Comment by Ambrose Bonnaire-Sergeant [ 23/Jun/15 8:50 AM ]

The implementation is fast and loose about the distinction of byte and Byte too – they're pretty much identical, since Clojure does the appropriate coercions at runtime. Also be careful about that.





[CTYP-270] "Method code too large!" with protocols (more than 38 functions in the protocol) Created: 17/Aug/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Johan Gall Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

You should be able to get the error with lein typed check on this.

https://gist.github.com/freakhill/2df1117738362d602672



 Comments   
Comment by Johan Gall [ 17/Aug/15 11:46 PM ]

"Method coDe too large!"

more than 39 functions





[CTYP-241] Let-aliased variables of plain Map lookups should update original map Created: 26/Jun/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Mark Feeney Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: let-aliasing, regression
Environment:

After commit https://github.com/clojure/core.typed/commit/960802



 Description   

Problem

Let-aliasing means we completely rely on the original binding's
type to find the type for locals derived from lookups on it. If
occurrence typing doesn't update the original binding, then even
very simple control flow does not register.

For example, in core.typed 0.3.7, the following code registers
e as an alias of (Key :foo)m.

(fn [m :- (Map Any Str)] :- String
  (let [e (:foo m)]
    (if e e "asdf")))
;;        ^
;;  Expected Str, actual (U nil Str)

e contains the correct propositions and object, however
update ignores propositions that update non-HMap types.

So in the test position, m is still of type (Map Any Str), which means path-type
infers Any for its aliased object (above). (Note: path-type should infer slightly better
types here, eg., this should return (U nil Str)).

Solution

The update case for keyword invocations on non-HMaps
need to intersect its known HMap type.

We now make it an error to assign an object to the result of looking up
a possibly-mutable map. ie.,

(fn [a :- Any] (:foo a))

has no object.

Correspondingly, update will throw an error if told to update via a keyword lookup
on a map type that is not a subtype of (U nil (Map Any Any)).

We cannot have objects that might be wrong — the formalism asserts that in

G |- e : t ; v+ | v- ; o}}, where G |- p and p |- e || v, that o = empty, or p(o) = v.

That means looking up an object o of an expression e must always
result in exactly its evaluation v. If we gave an object to

(fn [a :- Any] (:foo a))

that means two invocations of

((fn [a :- Any] (:foo a)) m)

must return exactly the same value — for a mutable m this is clearly false.

Interestingly, this has worked fine in practice until let-aliasing, by compensating
in the update function. We basically only update types that are immutable, checked
at the last minute in update.

Briefly, to handle this idea of "temporarily fake" objects, we probably need a predicate to validate
whether an object should be taken "seriously" as an actual, immutable, path. Then the formalism
might read:

G |- e : t ; v+ | v- ; o}}, where G |- p and p |- e || v, that o = empty, or if serious(o) then p(o) = v.

More information

Discussion here: https://groups.google.com/d/msg/clojure-core-typed/WO8dpY63N2Q/7UWBViNiIYEJ

git bisect code

(do (require '[clojure.core.typed :as t]) (t/cf (t/fn [m :- (t/Map t/Kw String)] :- String (or (:foo m) "asdf"))))

This stopped type checking after https://github.com/clojure/core.typed/commit/9608027bfaf4be268cfa12486c5ae6615d8517f1

bisect result:

9608027bfaf4be268cfa12486c5ae6615d8517f1 is the first bad commit
commit 9608027bfaf4be268cfa12486c5ae6615d8517f1
Author: Ambrose Bonnaire-Sergeant <...@gmail.com>
Date: Sat Jan 3 00:05:23 2015 +0000

enable aliasing support

Pull request:

Patch:
Commmit:
Release:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 18/Jul/15 2:21 AM ]

Minimal failing case:

(is-tc-e (fn [m :- (Map Kw Str)] :- Str 
           (let [e (:foo m)]
             (if e e "asdf"))))
;;                 ^
;;    Expected Str, actual (U nil Str)

This happens because let-aliasing relies on path-type solely to get a type for `e` and the type is not updated sufficiently based on this control flow.

Work started here: https://github.com/typedclojure/core.typed/pull/26





[CTYP-326] Let-aliasing breaks flow inference for results of `class` Created: 03/Jul/17  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Ambrose Bonnaire-Sergeant Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: let-aliasing, regression


 Description   

The following code complains a NPE is possible from .isArray,
but clearly the assertion prevents that. This issue is related
to let-aliasing, probably related to core.typed not knowing how
to update the type of `c` with the information that it's class
is non-nil.

(fn [a :- t/Any]
  (let [c (class a)
        _ (assert c)]
    (.isArray c)))





[CTYP-223] checking clojure.core/keep produces Internal Error--Cannot resolve type: Option Created: 31/May/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Blocker
Reporter: Vince Broz Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

org.clojure/core.typed "0.2.92"



 Description   

How to reproduce:

(t/cf (t/fn [] (keep even? [1 2 3])))

Observed result:

DEPRECATED SYNTAX (NO_SOURCE_PATH): All syntax is deprecated, use clojure.core.typed/All
Type Error (NO_SOURCE_PATH:1:16) Internal Error (NO_SOURCE_PATH:1:16) Cannot resolve type: Option
Hint: Is Option in scope?
Hint: Has Option's annotation been found via check-ns, cf or typed-deps?

ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)

Expected result:

(t/ASeq Integer) or something like that, I would guess.

Details:

broz@macmicro:~/src/foo$ lein try org.clojure/core.typed "0.2.92"
nREPL server started on port 63244 on host 127.0.0.1 - nrepl://127.0.0.1:63244
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (require ['clojure.core.typed :as 't])
nil
user=> (t/cf (t/fn [] (keep even? [1 2 3])))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 9649.842771 msecs"
core.typed initialized.
DEPRECATED SYNTAX (NO_SOURCE_PATH): All syntax is deprecated, use clojure.core.typed/All
Type Error (NO_SOURCE_PATH:1:16) Internal Error (NO_SOURCE_PATH:1:16) Cannot resolve type: Option
Hint: Is Option in scope?
Hint: Has Option's annotation been found via check-ns, cf or typed-deps?

ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)
user=>





[CTYP-225] Intersections of value types broken Created: 02/Jun/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

https://gist.github.com/joerupen/efb104ea81fce9d3a77d

;; Does core.type intersection not work on values?
 
(ns user-types.demo
  (:require [clojure.core.typed :as t]))
 
(t/defalias week-days "mon-fri"
  (t/U (t/Val :mon) (t/Val :tue) (t/Val :wed) 
       (t/Val :thu) (t/Val :fri) ))
 
(t/defalias party-days "days with party events"
  (t/U  (t/Val :fri) (t/Val :sat)))
 
(t/defalias party-days-of-the-week "days in the week with party events"
  (t/I week-days party-days))
 
(t/defn party-during-week [x :- party-days-of-the-week] x)
 
;; then in repl
(check-ns 'user-types.demo)
 
(t/cf (u/party-during-week :wed))
;; ups, no error? only friday should be allowed
=> [(t/I u/party-days u/week-days) {:then tt, :else ff}]





[CTYP-274] Inferred type for {{defn}} and {{typed/fn}} with the same body are different Created: 08/Sep/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: kshramt Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Following code passes a type check as expected:

(ann self-evaluating?
     [Any -> Boolean
      :filters {:then (is (U String Number) 0)
                :else (! (U String Number) 0)}])
(defn self-evaluating? [exp]
  (let [impl (typed/fn [x :- Any]
               (or (number? x)
                   (string? x)))]
    (impl exp)))

However, if I unwrap the typed/fn, it does not pass a type check:

(ann self-evaluating?
     [Any -> Boolean
      :filters {:then (is (U String Number) 0)
                :else (! (U String Number) 0)}])
(defn self-evaluating? [exp]
  (or (number? exp)
      (string? exp)))
Type Error (sicp/ch_4.clj:353:3) Expected result with filter {:then (is (U String Number) exp__#0), :else (! (U String Number) exp__#0)}, got filter {:then (& (| (is (U nil false) or__4238__auto____#0) (is Number exp__#0)) (| (! Number exp__#0) (! (U nil false) or__4238__auto____#0))), :else (& (| (is (U nil false) or__4238__auto____#0) (is Number exp__#0)) (| (! Number exp__#0) (! (U nil false) or__4238__auto____#0)))}
in: (if or__4238__auto__ or__4238__auto__ (string? exp))





[CTYP-209] method-type is broken Created: 08/Apr/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Timo Mihaljov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

[org.clojure/core.typed "0.2.84"]
[org.clojure/clojure "1.6.0"]



 Description   
reiska.core=> (t/method-type 'java.lang.Runtime/availableProcessors)

AssertionError Assert failed: Cannot find var: clojure.core.typed.check/Method->Type
(var? var)  clojure.core.typed.current-impl/v (current_impl.clj:19)





[CTYP-279] An invalid type annotation for a function with a record argument passes a type check Created: 25/Sep/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: kshramt Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Following code (unexpectedly) passes a type check.

(ns tst
  (:require
   [clojure.core.typed :refer [Int Kw ann] :as typed]))

(typed/defprotocol [[a :variance :covariant]] P
                   (f [p :- (P a)] :- a))

(typed/ann-record [[a :variance :covariant]] R [_f :- a])
(defrecord R [_f]
  P
  (f [self] _f))

(ann fr [(R Int) -> Kw])
(defn fr [x] (f x))





[CTYP-306] pred doesn't work for non-literal HVecs with varargs Created: 29/Jan/16  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Donald Ball Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

Predicate generation for HVec's do not support uniform variable parameters.

((t/pred (t/HVec [(t/Value :foo) t/Keyword *])) [:foo :bar])
CompilerException clojure.lang.ExceptionInfo: Internal Error (*cider-repl service*:97:17) :Protocol not supported in type->pred: * {:type-error :clojure.core.typed.errors/internal-error, :env {:line 97, :column 17, :file "*cider-repl service*", :ns spark.dev.repl}}, compiling:(*cider-repl service*:97:17)

Solution

This seems to be a symptom of * not being parsed correctly.

First, HVec's clearly ignores the variable parameters when they are parsed.

This is actually correctly done for quoted HVec types like '[Foo Bar *] here.

This change should fix things; the contract generation already works for quoted HVec's since it expects a rest entry,

Pull request:
Commit:
Version:



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 29/Jan/16 11:53 AM ]

The error is a bit odd. It may be that t/Keyword is the thing that's failing here.

Please try and isolate this error.

Comment by Ambrose Bonnaire-Sergeant [ 29/Jan/16 11:53 AM ]

Oh I see the issue. Cannot resolve Protocol called `*`!





[CTYP-277] Typechecking fails with internal assert error Created: 16/Sep/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Aliaksandr Barouski Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Clojure 1.7.0



 Description   

When I try to typecheck record, that implements untyped protocol, I get internal assertion error. Minimal example:

(defprotocol Lifecycle
  (start [component])
  (stop [component]))

(t/ann-record TestRec [host :- String
                       port :- Integer
                       connection :- String])
(defrecord TestRec [host port connection]
  Lifecycle
  (start [component]
    (let [connection (str "Host: " host ", port: " port)]
      (assoc component :connection connection)))
  (stop [component]
    (.close connection)))

Exception:

java.lang.AssertionError: Assert failed: (every? r/Type? types)
 at clojure.core.typed.type_ctors$In.doInvoke (type_ctors.clj:498)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invoke (core.clj:630)
    clojure.core.typed.assoc_utils/fn (assoc_utils.clj:40)
    clojure.core.typed.assoc_utils$fn__10$G__5__17.invoke (assoc_utils.clj:25)
    clojure.core.typed.type_ctors$reduce_type_transform$fn__7210$iter__7211__7217$fn__7218.invoke (type_ctors.clj:2200)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:507)
    clojure.core/seq (core.clj:137)
    clojure.core$some.invoke (core.clj:2569)
    clojure.core.typed.type_ctors$union_or_nil.invoke (type_ctors.clj:2180)
    clojure.core.typed.type_ctors$reduce_type_transform.doInvoke (type_ctors.clj:2195)
    clojure.lang.RestFn.invoke (RestFn.java:494)

Debug print in error position:

(:types new-i) => #{{:the-class clojure.core.typed.test.records3.TestRec,
    :variances nil,
    :poly? nil,
    :fields
    {host {:id java.lang.String},
     port {:id java.lang.Integer},
     connection {:id java.lang.String}},
    :record? true}
   {:variances nil,
    :poly? nil,
    :the-class clojure.core.typed.test.records3.Lifecycle}}

(map #(assoc-type-pairs % assoc-entry) (:types new-i)) =>
({:the-class clojure.core.typed.test.records3.TestRec,
  :variances nil,
  :poly? nil,
  :fields
  {host {:id java.lang.String},
   port {:id java.lang.Integer},
   connection {:id java.lang.String}},
  :record? true}
 nil)





[CTYP-140] HSequential things should correctly erase dotted arguments Created: 09/May/14  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

These unit tests should pass.






[CTYP-275] Bad call to path-type: nil Created: 15/Sep/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: 0.3.11
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Mark Feeney Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Discussion: https://groups.google.com/d/msg/clojure-core-typed/-4XzTLD1LNE/LuJqMuNzAgAJ

(t/cf (t/fn [x :- (t/Option '[t/Num])] (let [[a] x] a)))
Type Error (...) Internal Error (...) Bad call to path-type: nil, ({:idx 0})





[CTYP-88] with-meta doesn't type check with vectors or hash-maps. Created: 16/Oct/13  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Russell Mull Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

clojure 1.5.1
core.typed 0.2.13



 Description   
(cf (with-meta 'a {})) 
;; => (Value a)  ; expected result

(cf (with-meta [] {}))
;; => AssertionError Assert failed: 1: Inferred type [] is not between bounds Nothing and clojure.lang.IObj
(and (subtype? inferred upper-bound) (subtype? lower-bound inferred))  clojure.core.typed.cs-gen/subst-gen/fn--10379 (cs_gen.clj:1333)

This also fails with an empty hash-map literal. Lists and sets work.






[CTYP-102] large hashmaps: failure to discover subtype and error-output to complex to understand Created: 02/Feb/14  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Cees van Kemenade Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: error-reporting, hash-map
Environment:

core.typed 0.2.25


Attachments: File longOutput.clj     File show-error.output    

 Description   

I am applying core.typed to a project that processes sequences of fairly large hash-maps. I run into two issues:
1. The error output is to large to be interpreted by a human (4k per error)
2. The reported error seems to be incorrect as the expected-type and actual type seem to match.

I came to this conclusion by writing a function that compared the expected type and the actuals type. This function is included too and might be an example of how to produce more compact and readible output for errors on large hash-maps.

The longOutput.clj contains the function that fails (derive-sms_msg-fmt-fail ..) and the nearly similar function (derive-sms_msg-fmt ..) that passes (check-ns).

The file also contains function (show-error) which prints a copy of the type-error and subsequently analyses the derived type with the expected type. The derived type is a union of the expected type and some derivatives based on the inclusion of optional keys. So I as far as I can see the union is subtype of the expected type and the reported error is incorrect.

An example of the error-analysis is included in the file show-error.output.



 Comments   
Comment by Cees van Kemenade [ 03/Feb/14 2:40 AM ]

PS: I could imagine that the current (show-error ..) could service as a basis for more compact error-messages on large hashmaps (using length of output as a criterium to decide whether the current error-format or the diffence-analysis results in the most compact error-report).

PS: I strongly believe in the big advantages of a static type-checker. But with the current error-messages it is nearly impossible to migrate a project involving large hash-maps due to the volumunuous error-output.

Comment by Ambrose Bonnaire-Sergeant [ 03/Feb/14 11:00 PM ]

Hi Cees,

Thanks for the detailed report, it really helps. I'll look into this.





[CTYP-222] if-let on an hmap with an optional entry always expected to succeed Created: 30/May/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Vince Broz Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: hmap, occurrence-typing


 Description   

How to reproduce:

(t/cf (t/fn [m :- (t/HMap :optional {:a String} :complete? true)] (if-let [b (get m :a)] true)))

Observed result:

[[(t/HMap :optional {:a String} :complete? true) -> true :filters {:then tt, :else ff}] {:then tt, :else ff}]

Expected result (pseudeocode):

[(t/HMap :optional {:a String} :complete? true) -> (t/U nil true)]

This is what you get if you replace the if-let above with if.

Return type should be (t/Option true), as the if-let will result in a nil return if the :a key is not set on the map.

Details:

broz@macmicro:~$ grep try ~/.lein/profiles.clj
   [lein-try "0.4.3"]
broz@macmicro:~$ lein try org.clojure/core.typed
nREPL server started on port 52406 on host 127.0.0.1 - nrepl://127.0.0.1:52406
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (require ['clojure.core.typed :as 't])
nil
user=> (t/cf (t/fn [m :- (t/HMap :optional {:a String} :complete? true)] (if-let [b (get m :a)] true)))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 14055.732654 msecs"
core.typed initialized.
[[(t/HMap :optional {:a String} :complete? true) -> true :filters {:then tt, :else ff}] {:then tt, :else ff}]





[CTYP-32] Cannot instantiate variables that have bounds Created: 29/Jul/13  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Ambrose Bonnaire-Sergeant Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: newbie


 Description   

Trying to implement this example: http://www.scala-lang.org/node/136

The result: core.typed doesn't know that other bounded type variables can be substituted.

https://gist.github.com/frenchy64/6110077






[CTYP-204] Assoc doesn't work with multiple entries Created: 10/Mar/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Colin Yates Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

(from https://groups.google.com/d/msg/clojure-core-typed/4z_7WnqZsyI/53jlUHQfWhEJ)

The following code:

(t/ann new-ar (t/All [[m :< (t/Map t/Any t/Any)]] [m -> (t/Assoc m ':id Number ':version Number)]))
(defn new-ar
  [detail]
  {:post [(not (nil? (:id %)))
          (zero? (:version %))]}
  (assoc detail :id 10 :version 0))

gives the following error:

Type Error (qfi/health/core/domain/model/common.clj:40:3) Cannot assoc args `[(clojure.core.typed/Val :id) {:then tt, :else ff}] [(clojure.core.typed/Val 10) {:then tt, :else ff}] [(clojure.core.typed/Val :version) {:then tt, :else ff}] [(clojure.core.typed/Val 0) {:then tt, :else ff}]` on m
in: (assoc detail :id 10 :version 0)





[CTYP-219] RPS example does not type check Created: 22/May/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: victor chung Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

osx
clojure 1.6



 Description   

Code is here:

https://gist.github.com/kindlychung/9f932ae4c9b752f87431



 Comments   
Comment by victor chung [ 22/May/15 2:57 AM ]

How do I edit an issue?
Sorry, this should have been marked as defect instead of enhancement.





[CTYP-201] Calling a multimethod from a protocol function breaks the type checker Created: 27/Feb/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Reno Reckling Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When i call a multimethod from within a protocol implementation, i receive a long error.

Minimum working example including error output:
https://github.com/exi/core-typed-errors

Code:

(ns example.core
  (:import java.io.File)
  (:require [clojure.core.typed :as t]))

(declare dispatcher)

(t/ann-protocol MProto
                myfn (t/IFn [MProto File -> String]))
(defprotocol MProto
  (myfn [this obj]))

(t/ann-record MRec [name :- String])
(defrecord MRec [name]
  MProto
  (myfn [this obj] (dispatcher this obj)))

(t/ann dispatcher (t/IFn [MRec File -> String]))
(defmulti dispatcher (fn [rec obj] (class obj)))

(defmethod dispatcher
  File
  [rec obj]
  (:name rec))

(defn -main [& args]
  (let [rec (MRec. "myname")
        file (File. ".")]
    (when (not (nil? file))
      (println (myfn rec file)))))

Error message:

Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 3564.305528 msecs"
core.typed initialized.
Start collecting example.core
Finished collecting example.core
Collected 1 namespaces in 681.706266 msecs
Not checking clojure.core.typed (does not depend on clojure.core.typed)
Start checking example.core
nil Not checking example.core/MProto definition
13:  Not checking example.core/->MRec definition
Checked example.core in 1019.900549 msecs
WARNING: Type Checker: Definition missing: clojure.core/assert-same-protocol 
Hint: Use :no-check metadata with ann if this is an unchecked var
WARNING: Type Checker: Definition missing: clojure.core/-cache-protocol-fn 
Hint: Use :no-check metadata with ann if this is an unchecked var
WARNING: Type Checker: Definition missing: clojure.core/-reset-methods 
Hint: Use :no-check metadata with ann if this is an unchecked var
Checked 2 namespaces  in 1717.619162 msecs
Type Error (example/core.clj:9:1) Polymorphic function clojure.core/alter-meta! could not be applied to arguments:
Polymorphic Variables:
	b

Domains:
	clojure.lang.IReference [(t/U nil (IPersistentMap t/Any t/Any)) b ... b -> (t/U nil (IPersistentMap t/Any t/Any))] b ... b

Arguments:
	(Var t/Any t/Any) (t/All [b c d] (t/IFn [(t/Map b c) b c -> (t/Map b c)] [(t/Vec d) t/AnyInteger d -> (t/Vec d)])) (t/Val :doc) nil

Ranges:
	(t/U nil (IPersistentMap t/Any t/Any))

in: (clojure.core/alter-meta! (var example.core/MProto) clojure.core/assoc :doc nil)
in: (clojure.core/alter-meta! (var example.core/MProto) clojure.core/assoc :doc nil)


Type Error (example/core.clj:9:1) Untyped var reference: clojure.core/assert-same-protocol
Hint: Add the annotation for clojure.core/assert-same-protocol via check-ns or cf
in: (var clojure.core/assert-same-protocol)


Type Error (example/core.clj) Cannot call instance method example.core.MProto/myfn on type clojure.core.typed/Any
in: (.myfn gf__this__763 gf__obj__764)


Type Error (example/core.clj) Instance method example.core.MProto/myfn could not be applied to arguments:


Domains:
	Object

Arguments:
	t/Any

Ranges:
	(t/U nil Object)

in: (.myfn gf__this__763 gf__obj__764)
in: (.myfn gf__this__763 gf__obj__764)


Type Error (example/core.clj) Instance field __methodImplCache expected clojure.lang.AFunction, actual [clojure.core.typed/Any clojure.core.typed/Any -> clojure.core.typed/Any]
in: (.-__methodImplCache G__753)


Type Error (example/core.clj) Static method clojure.lang.Util/classOf could not be applied to arguments:


Domains:
	Object

Arguments:
	t/Any

Ranges:
	(t/U nil Class)

in: (clojure.lang.Util/classOf gf__this__766)
in: (clojure.lang.Util/classOf gf__this__766)


Type Error (example/core.clj) Cannot call instance method clojure.lang.MethodImplCache/fnFor on type (clojure.core.typed/U nil clojure.lang.MethodImplCache)
in: (.fnFor cache__5915__auto__ (clojure.lang.Util/classOf gf__this__766))


Type Error (example/core.clj) Cannot invoke type: IFn
in: (f__5916__auto__ gf__this__766 gf__obj__767)


Type Error (example/core.clj) Unannotated var clojure.core/-cache-protocol-fn
Hint: Add the annotation for clojure.core/-cache-protocol-fn via check-ns or cf
in: clojure.core/-cache-protocol-fn


Type Error (example/core.clj) Instance field __methodImplCache expected clojure.lang.AFunction, actual [clojure.core.typed/Any clojure.core.typed/Any -> Error]
in: (.-__methodImplCache f__5918__auto__)


Type Error (example/core.clj) Type mismatch:

Expected: 	(t/U nil MethodImplCache)

Actual: 	t/Any
in: cache__5917__auto__


Type Error (example/core.clj:9:1) Polymorphic function clojure.core/alter-var-root could not be applied to arguments:
Polymorphic Variables:
	w
	r
	b

Domains:
	(t/Var2 w r) [r b ... b -> w] b ... b

Arguments:
	(Var t/Any t/Any) (t/All [k v] (t/IFn [nil * -> nil] [(clojure.lang.IPersistentMap k v) (clojure.lang.IPersistentMap k v) * -> (clojure.lang.IPersistentMap k v)] [(t/Option (clojure.lang.IPersistentMap k v)) * -> (t/Option (clojure.lang.IPersistentMap k v))])) (t/HMap :mandatory {:method-builders (APersistentMap (t/Var2 t/Nothing t/Any) [t/Any -> [t/Any t/Any -> Error] :filters {:then tt, :else ff}]), :method-map (t/HMap :mandatory {:myfn (t/Val :myfn)} :complete? true), :var (Var t/Any t/Any), :sigs (t/HMap :mandatory {:myfn (t/HMap :mandatory {:file (t/Val "example/core.clj"), :line (t/Val 10), :column (t/Val 4), :end-line (t/Val 10), :end-column (t/Val 9), :name (t/Val myfn), :arglists (ISeq (t/HVec [(t/Val this) (t/Val obj)])), :doc nil} :complete? true)} :complete? true), :on (t/Val example.core.MProto), :on-interface (t/Val example.core.MProto)} :complete? true)

Ranges:
	w

in: (clojure.core/alter-var-root (var example.core/MProto) clojure.core/merge (clojure.core/assoc {:on (quote example.core.MProto), :on-interface example.core.MProto} :sigs (quote {:myfn {:doc nil, :arglists ([this obj]), :name myfn, :end-column 9, :end-line 10, :column 4, :line 10, :file "example/core.clj"}}) :var (var example.core/MProto) :method-map {:myfn :myfn} :method-builders {(clojure.core/intern clojure.core/*ns* (clojure.core/with-meta (quote myfn) (clojure.core/merge (quote {:doc nil, :arglists ([this obj]), :name myfn, :end-column 9, :end-line 10, :column 4, :line 10, :file "example/core.clj"}) {:protocol (var example.core/MProto)}))) (fn* ([cache__5917__auto__] (let* [G__754 (fn* ([gf__this__763 gf__obj__764] (.myfn gf__this__763 gf__obj__764))) f__5918__auto__ (fn* G__753 ([gf__this__766 gf__obj__767] (let* [cache__5915__auto__ (.-__methodImplCache G__753) f__5916__auto__ (.fnFor cache__5915__auto__ (clojure.lang.Util/classOf gf__this__766))] (if f__5916__auto__ (f__5916__auto__ gf__this__766 gf__obj__767) ((clojure.core/-cache-protocol-fn G__753 gf__this__766 example.core.MProto G__754) gf__this__766 gf__obj__767)))))] (do (set! (.-__methodImplCache f__5918__auto__) cache__5917__auto__) f__5918__auto__))))}))
in: (clojure.core/alter-var-root (var example.core/MProto) clojure.core/merge (clojure.core/assoc {:on (quote example.core.MProto), :on-interface example.core.MProto} :sigs (quote {:myfn #}) :var (var example.core/MProto) ...))


Type Error (example/core.clj) Unannotated var clojure.core/-reset-methods
Hint: Add the annotation for clojure.core/-reset-methods via check-ns or cf
in: clojure.core/-reset-methods


Type Checker: Found 13 errors
Found errors
Subprocess failed





[CTYP-191] Bad type syntax when parsing types of macro-generated anonymous functions from required namespaces (when the types are composed, for instance (Option AnyInteger)) Created: 09/Jan/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Johan Gall Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   
(defmacro lol2 []
      (let [a (list `typed/Option `typed/AnyInteger)]
        `(fn [] :- ~a 1)))
    
    
    (defmacro lol []
      `(fn [] :- (typed/Option typed/AnyInteger) 1))

    (clojure.core.typed/def lol*2 :- [-> (typed/Option typed/AnyInteger)]
      (lol2))
    
    (clojure.core.typed/def lol* :- (typed/Option typed/AnyInteger)
      (lol))

I put this code in namespace A, both typecheck without problem.

When A is depended on by namespace B, when B is checked
lol*2 is completely fine but lol* crashes with

"Bad type syntax: (clojure.core.typed/Option clojure.core.typed/AnyInteger)"

The following works fine.

(defmacro lol**3 []
      `(fn [] :- typed/AnyInteger 1))
    
    (clojure.core.typed/def lol*3 :- typed/AnyInteger
      (lol**3))





[CTYP-195] Support for clojure.core/extend is broken when used with typed.core/defprotocol Created: 15/Jan/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Daniel Ziltener Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

core.typed 0.2.77



 Description   

Using extend with a protocol defined using typed.core/defprotocol, the following error occurs:

Type Error (client/clojurefx.clj:31:1) Internal Error (client/clojurefx.clj:31:1) Expecting Protocol type, found clojure.core.typed.type_rep.TypeFn@38c0769f






[CTYP-197] No matching arities when defining multiple arity protocol method Created: 25/Jan/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: 0.2
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Joshua Griffith Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: bug, defprotocol, deftype
Environment:

Clojure 1.6.0 and 1.7.0-alpha5


Attachments: File arity.clj     Text File typecheck.log    

 Description   

When defining multiple-arity protocol methods with clojure.core.typed/defprotocol, deftypes implementing these methods fail to typecheck with "No matching arities" errors. See attached test case.



 Comments   
Comment by Johan Gall [ 08/May/15 1:18 AM ]

i found a quite similar problem with defrecord. Is there some kind of workaround?

project.clj http://pastebin.com/bn6giuvH
core_typed_bug/core.clj http://pastebin.com/JjfhWLSH
error message http://pastebin.com/djsAicd1

with clojure 1.7.0-beta2 and core.typed 0.2.87

(ns core-typed-bug.core
  (:require [ clojure.core.typed :as t ]))
 
(t/defprotocol P
  (f
   [a] :- Any
   [a b :- Any] :- Any))
 
(t/ann-record R [])
(defrecord R []
  P
  (f [a] 1)
  (f [a b] 2))

will give the following arity related errors:

Collected 1 namespaces in 758.831468 msecs
Not checking clojure.core.typed (does not depend on clojure.core.typed)
Start checking core-typed-bug.core
10:  Not checking core-typed-bug.core/->R definition
Checked core-typed-bug.core in 923.152062 msecs
Checked 2 namespaces  in 1702.704416 msecs
Type Error (core_typed_bug/core.clj:10:1) No matching arities: [R t/Any -> t/Any]
in: (f [a] 1)
 
 
Type Error (core_typed_bug/core.clj:10:1) No matching arities: [R -> t/Any] in: (f [a b] 2)
 
 
Type Checker: Found 2 errors
Found errors




[CTYP-282] Internal error with t/defn, sort-by and no refer all Created: 24/Oct/15  Updated: 03/Dec/17

Status: Reopened
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Major
Reporter: Vince Broz Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: None
Environment:

org.clojure/core.typed 0.3.12



 Description   

How to reproduce:

(require 'clojure.core.typed)
(clojure.core.typed/cf (clojure.core.typed/defn foo [] sort-by))

It does seem to reproduce somewhat flakily within existing REPL environments depending on what you've run in the past. This will consistently reproduce it:

docker run -i -t clojure bash
echo '{:user {:plugins [[lein-try "0.4.3"]]}}' > ~/.lein/profiles.clj
lein try org.clojure/core.typed

(require 'clojure.core.typed) ;; does not work with refer all
(clojure.core.typed/cf (clojure.core.typed/defn foo [] sort-by))

Observed result:

Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 5836.201655 msecs"
core.typed initialized.
DEPRECATED SYNTAX (/tmp/form-init6540853594514266546.clj:1:24): All syntax is deprecated, use clojure.core.typed/All
Type Error (/tmp/form-init6540853594514266546.clj:1:24) Internal Error (/tmp/form-init6540853594514266546.clj:1:24) Cannot resolve type: IFn
Hint: Is IFn in scope?
Hint: Has IFn's annotation been found via check-ns, cf or typed-deps?
Error

Desired result:

Correct type returned.



 Comments   
Comment by Vince Broz [ 03/Dec/17 8:06 PM ]

Hi! I just reproduced this issue using the docker recipe above (which uses the current version of org.clojure/core.typed. Did you try using the Docker recipe? Suggest reopening.

Comment by Ambrose Bonnaire-Sergeant [ 03/Dec/17 9:11 PM ]

Thanks, I appreciate the followup! I think there's something fishy going on with a subset of the base type environment that's shared between the CLJ and CLJS checkers.





[CTYP-76] Support KwArgsSeq in apply Created: 01/Oct/13  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Leonardo Borges Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: idiom


 Description   

Applying keyword arguments doesn't work properly at the moment.

To reproduce:

Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java
(cf (ann fn2 [(HMap :mandatory {}) & {} -> '[] ]))
(cf (defn fn2 [m & args]
      []))

(cf (ann fn1 [(HMap :mandatory {}) & {} -> Boolean ]))
(cf (defn fn1 [m & args]
      (empty? (apply fn2 (cons m args)))))

;;This is how it's used:
 (fn1 {} :a string? :b keyword? :c another-boolean-fn?)

;; And this is the type error:

;; Type Error (bouncer.core:2:28) Polymorphic function clojure.core/cons could not be applied to arguments:
;; Polymorphic Variables:
;;   x

;; Domains:
;; 	x (Option (clojure.lang.Seqable x))

;; Arguments:
;; 	(HMap :mandatory {}) (KwArgsSeq)

;; Ranges:
;; 	(clojure.lang.ASeq x)

;; in: (clojure.core/cons m args)

;; in: (clojure.core/empty? (clojure.core/apply bouncer.core/fn2 (clojure.core/cons m args)))

;;  [2 times]
;;  [2 times]
;; Type Error (bouncer.core:2:17) Bad arguments to apply: 

;; Target: 	(Fn [(HMap :mandatory {}) & {} -> []])

;; Arguments:	Error

;; in: (clojure.core/empty? (clojure.core/apply bouncer.core/fn2 (clojure.core/cons m args)))

;;  [2 times]
;;  [2 times]
;; ExceptionInfo Type Checker: Found 2 errors  clojure.core/ex-info (core.clj:4327)

;; Mark set





[CTYP-129] select-keys on HMap returns Map with union key and value types Created: 30/Mar/14  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Timo Mihaljov Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

core.typed 0.2.40



 Description   

Currently select-keys on an HMap returns a Map with unions for keys and values.

=> (t/cf {:foo 1, :bar "2", :baz \3})
[(HMap :mandatory {:baz (Value \3), :bar (Value "2"), :foo (Value 1)} :complete? true) {:then tt, :else ff}]

=> (t/cf (select-keys {:foo 1, :bar "2", :baz \3}
                      [:foo :bar]))
(t/Map (U (Value :baz) (Value :foo) (Value :bar)) (U (Value 1) (Value \3) (Value "2")))

This results in type errors when select-keys is used to remove extra keys from an HMap.

Expected behaviour: select-keys should return an HMap with a subset of the :mandatory keys of its input HMap.






[CTYP-221] group-by produces "Cannot resolve type: Seqable" Created: 29/May/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Minor
Reporter: Vince Broz Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

How to reproduce:

broz@macmicro:~$ grep try ~/.lein/profiles.clj
[lein-try "0.4.3"]
broz@macmicro:~$ lein try org.clojure/core.typed
nREPL server started on port 56675 on host 127.0.0.1 - nrepl://127.0.0.1:56675
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b26
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e

user=> (require ['clojure.core.typed :as 't])
nil
user=> (t/cf (t/defn repro-core-typed-9 [m :- (t/Seqable String)] (group-by identity m)))
Initializing core.typed ...
Building core.typed base environments ...
Finished building base environments
"Elapsed time: 10484.613659 msecs"
core.typed initialized.
DEPRECATED SYNTAX (NO_SOURCE_PATH): All syntax is deprecated, use clojure.core.typed/All
DEPRECATED SYNTAX (NO_SOURCE_PATH): U syntax is deprecated, use clojure.core.typed/U
Type Error (NO_SOURCE_PATH:1:60) Internal Error (NO_SOURCE_PATH:1:60) Cannot resolve type: Seqable
Hint: Is Seqable in scope?
Hint: Has Seqable's annotation been found via check-ns, cf or typed-deps?
Error
user=>

Expected result:

Should not give an internal error.

Note:

core.typed rules! I'm finding it very useful for my project and has found many bugs before they hit production--it's a great tool to have access to.






[CTYP-301] Abstract over keyword arguments Created: 19/Nov/15  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Ambrose Bonnaire-Sergeant Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Problem

If two functions take similar keyword arguments, we have to write them out twice.

(ann make-contract [& :optional {:name (U Symbol String)
                                 :first-order [Any :-> Any]
                                 :projection [Blame :-> [Any :-> Any]]
                                 :flat? Boolean}
                    :-> Contract])

(ann make-flat-contract [& :optional {:name (U Symbol String)
                                      :first-order [Any :-> Any]
                                      :projection [Blame :-> [Any :-> Any]]
                                      :flat? Boolean}
                         :-> Contract])

Since HMap syntax is very similar and keyword arguments often flow into HMap types, it would be great to just specify these as HMap types.

(defalias KW 
  (HMap :optional {:name (U Symbol String)
                   :first-order [Any :-> Any]
                   :projection [Blame :-> [Any :-> Any]]
                   :flat? Boolean}))
(ann make-contract [& :HMap KW :-> Contract])

(ann make-flat-contract [& :HMap KW :-> Contract])

Questions

What does a union of HMap's mean?

eg.

(defalias KW 
  (U '{:a Int}
     '{:b Int}))
(ann make-contract [& :HMap KW :-> Contract])

What does nil mean?

(defalias KW 
  (U '{:a Int}
     nil))
(ann make-contract [& :HMap KW :-> Contract])





[CTYP-134] Allow namespace aliases in `ann` Created: 14/Apr/14  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Oskar Thorén Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: newbie


 Description   

If I have a function which uses an external library, I want to be able to write:

(ann ^:no-check json/parse-string [String Boolean -> Map])

instead of

(ann ^:no-check cheshire.core/parse-string [String Boolean -> Map])

since that's the form I use in my namespace.



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 14/Apr/14 6:43 AM ]

This might also apply to `ann-protocol`.

Comment by Robin Hermansson [ 06/Sep/16 12:29 AM ]

Is anyone working on this?

Comment by Ambrose Bonnaire-Sergeant [ 08/Sep/16 1:48 PM ]

No, patch welcome.





[CTYP-143] extend & extend-protocol with (Class/forName "[B") as Class dispatch value fails Created: 12/May/14  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Clojure Checker
Affects Version/s: None
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Max Penet Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

it can be observed in this example: https://gist.github.com/mpenet/23fd53aabc853eb7e565

using extend instead of extend-protocol returns a type error:

Type Error (qbits/alia/codec.clj:75:1) Must provide
                a Class or nil as first argument to extend, got
                java.lang.Class

This issue in clj.core could also be of interest http://dev.clojure.org/jira/browse/CLJ-1381






[CTYP-72] merge doesn't seem to like records Created: 28/Sep/13  Updated: 03/Dec/17

Status: Open
Project: core.typed
Component/s: Core type system
Affects Version/s: 0.2, 0.3.0
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Julian Birch Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I'm pretty sure this should pass

(ns moonrise
  (:require [clojure.core.typed :refer :all]))

(ann-record X [a :- Number])
(defrecord X [a])

(ann x X)
(def x (merge (X. 3) {:z 4}))

but it gives

Type Error (moonrise:8:8) Polymorphic function clojure.core/merge could not be applied to arguments:
Polymorphic Variables:
	k
	v

Domains:
	nil *
	(clojure.lang.IPersistentMap k v) (clojure.lang.IPersistentMap k v) *
	(Option (clojure.lang.IPersistentMap k v)) *

Arguments:
	moonrise.X (HMap :mandatory {:z (Value 4)} :complete? true)

Ranges:
	nil
	(clojure.lang.IPersistentMap k v)
	(Option (clojure.lang.IPersistentMap k v))

with expected type:
	moonrise.X

in: (clojure.core/merge (new moonrise.X 3) (quote {:z 4}))
in: (def x (clojure.core/merge (new moonrise.X 3) (quote {:z 4})))


Type Checker: Found 1 error





[CTYP-242] adding stop-gap annotation for 'hash-map' results in runtime exception Created: 30/Jun/15  Updated: 04/Dec/17

Status: Reopened
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: Backlog

Type: Defect Priority: Minor
Reporter: Jonathan Leonard Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: annotation, bug
Environment:

Mac OS X 10.10.3

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

$ lein --version
Leiningen 2.5.1 on Java 1.8.0_45 Java HotSpot(TM) 64-Bit Server VM



 Description   

Adding the following annotation results in a runtime exception:

(t/ann ^:no-check clojure.core/hash-map
     [t/Any * -> (t/Map t/Any t/Any)])

Exception:

$ lein typed check 
Retrieving org/clojure/core.typed/0.3.3/core.typed-0.3.3.pom from central
Retrieving org/clojure/core.typed-pom/0.3.3/core.typed-pom-0.3.3.pom from central
Retrieving org/clojure/core.typed.rt/0.3.3/core.typed.rt-0.3.3.pom from central
Retrieving org/clojure/clojure/1.7.0-RC2/clojure-1.7.0-RC2.pom from central
Retrieving org/clojure/core.typed.rt/0.3.3/core.typed.rt-0.3.3.jar from central
Retrieving org/clojure/core.typed/0.3.3/core.typed-0.3.3.jar from central
Initializing core.typed ...
Building core.typed base environments ...
Exception in thread "main" java.lang.AssertionError: Assert failed: (every? r/Bounds? bbnds), compiling:(/private/var/folders/fg/8xpsfgln1_s0cwh3f1ksxtjr0000gq/T/form-init6446670678682645381.clj:1:124)
	at clojure.lang.Compiler.load(Compiler.java:7142)
	at clojure.lang.Compiler.loadFile(Compiler.java:7086)
	at clojure.main$load_script.invoke(main.clj:274)
	at clojure.main$init_opt.invoke(main.clj:279)
	at clojure.main$initialize.invoke(main.clj:307)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.doInvoke(main.clj:420)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.AssertionError: Assert failed: (every? r/Bounds? bbnds)
	at clojure.core.typed.type_ctors$TypeFn_STAR_.invoke(type_ctors.clj:1040)
	at clojure.core.typed.type_ctors$TypeFn_STAR_.invoke(type_ctors.clj:1041)
	at clojure.core.typed.base_env_helper$declared_kind_for_rclass.invoke(base_env_helper.clj:179)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env$fn__20119$fn__20125$iter__20126__20130$fn__20131.invoke(base_env_clj_rclass.clj:27)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.RT.seq(RT.java:484)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core$dorun.invoke(core.clj:2855)
	at clojure.core$doall.invoke(core.clj:2871)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env$fn__20119$fn__20125.invoke(base_env_clj_rclass.clj:27)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env$fn__20119.invoke(base_env_clj_rclass.clj:27)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env_clj_rclass$generator_init_altered_env.invoke(base_env_clj_rclass.clj:25)
	at clojure.core.typed.base_env_clj_rclass$init_altered_env.invoke(base_env_clj_rclass.clj:25)
	at clojure.core.typed.base_env_clj_rclass$reset_rclass_env_BANG_.invoke(base_env_clj_rclass.clj:476)
	at clojure.core.typed.base_env$generator_init_alias_env$fn__20466.invoke(base_env.clj:64)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env$generator_init_alias_env.invoke(base_env.clj:64)
	at clojure.core.typed.base_env$init_alias_env.invoke(base_env.clj:64)
	at clojure.core.typed.base_env$reset_alias_env_BANG_.invoke(base_env.clj:67)
	at clojure.core.typed.base_env$reset_clojure_envs_BANG_$fn__20869$fn__20870.invoke(base_env.clj:1871)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.base_env$reset_clojure_envs_BANG_$fn__20869.invoke(base_env.clj:1870)
	at clojure.core.typed.base_env$reset_clojure_envs_BANG_.invoke(base_env.clj:1870)
	at clojure.core.typed.reset_env$reset_envs_BANG_.invoke(reset_env.clj:20)
	at clojure.core.typed.init$load_impl$fn__1728$fn__1729.invoke(init.clj:113)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.init$load_impl$fn__1728.invoke(init.clj:112)
	at clojure.core.typed.init$load_impl.invoke(init.clj:112)
	at clojure.core.typed.load_if_needed$load_if_needed.invoke(load_if_needed.clj:22)
	at clojure.core.typed$fn__919.invoke(typed.clj:54)
	at clojure.core.typed$fn__1678.doInvoke(typed.clj:2256)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval1698$fn__1699.invoke(form-init6446670678682645381.clj:1)
	at user$eval1698.invoke(form-init6446670678682645381.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6703)
	at clojure.lang.Compiler.eval(Compiler.java:6693)
	at clojure.lang.Compiler.load(Compiler.java:7130)
	... 11 more
Subprocess failed


 Comments   
Comment by Jonathan Leonard [ 30/Jun/15 2:31 PM ]

The above exception call stack is for version: 0.3.3.

Version 0.3.0-alpha5 produces a different exception call stack:

Exception in thread "main" java.lang.AssertionError: Assert failed: (let [[derived-props derived-atoms] %] (and (every? (some-fn fl/ImpFilter? fl/OrFilter? fl/AndFilter?) derived-props) (every? (some-fn fl/TypeFilter? fl/NotTypeFilter?) derived-atoms))), compiling:(/private/var/folders/fg/8xpsfgln1_s0cwh3f1ksxtjr0000gq/T/form-init3689436395269879959.clj:1:124)
	at clojure.lang.Compiler.load(Compiler.java:7142)
	at clojure.lang.Compiler.loadFile(Compiler.java:7086)
	at clojure.main$load_script.invoke(main.clj:274)
	at clojure.main$init_opt.invoke(main.clj:279)
	at clojure.main$initialize.invoke(main.clj:307)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.doInvoke(main.clj:420)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.AssertionError: Assert failed: (let [[derived-props derived-atoms] %] (and (every? (some-fn fl/ImpFilter? fl/OrFilter? fl/AndFilter?) derived-props) (every? (some-fn fl/TypeFilter? fl/NotTypeFilter?) derived-atoms)))
	at clojure.core.typed.update$combine_props.invoke(update.clj:58)
	at clojure.core.typed.check.let$check_let$fn__13761$fn__13769.invoke(let.clj:83)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core$update_in.doInvoke(core.clj:5698)
	at clojure.lang.RestFn.invoke(RestFn.java:445)
	at clojure.lang.AFn.applyToHelper(AFn.java:160)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core.contracts.constraints$apply_contract$fn__413.doInvoke(constraints.clj:174)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
	at clojure.lang.RestFn.invoke(RestFn.java:436)
	at clojure.core.typed.check.let$check_let$fn__13761.invoke(let.clj:79)
	at clojure.core.protocols$fn__6086.invoke(protocols.clj:143)
	at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
	at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
	at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6289)
	at clojure.core.typed.check.let$check_let.doInvoke(let.clj:103)
	at clojure.lang.RestFn.invoke(RestFn.java:445)
	at clojure.core.typed.check$check _COLON_let14930.doInvoke(check.clj:1629)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check.do$check_do$fn__12802$fn__12805.invoke(do.clj:41)
	at clojure.core.typed.check.do$check_do$fn__12802.invoke(do.clj:33)
	at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:58)
	at clojure.core.protocols$fn__6093.invoke(protocols.clj:98)
	at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
	at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
	at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6289)
	at clojure.core.typed.check.do$check_do.invoke(do.clj:61)
	at clojure.core.typed.check$check _COLON_do14821.doInvoke(check.clj:1382)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check.fn_method_one$check_fn_method1$fn__13601.invoke(fn_method_one.clj:183)
	at clojure.core.typed.check.fn_method_one$check_fn_method1.doInvoke(fn_method_one.clj:173)
	at clojure.lang.RestFn.invoke(RestFn.java:464)
	at clojure.core.typed.check.special.fn$check_anon$fn__13996.invoke(fn.clj:44)
	at clojure.lang.AFn.applyToHelper(AFn.java:178)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$map$fn__4260.invoke(core.clj:2578)
	at clojure.core$map$fn__4245.invoke(core.clj:2559)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.RT.seq(RT.java:484)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core.protocols$seq_reduce.invoke(protocols.clj:30)
	at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
	at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
	at clojure.core$reduce.invoke(core.clj:6289)
	at clojure.core$into.invoke(core.clj:6341)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core.contracts.constraints$apply_contract$fn__413.doInvoke(constraints.clj:175)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.core$mapv.doInvoke(core.clj:6360)
	at clojure.lang.RestFn.invoke(RestFn.java:580)
	at clojure.core.typed.check.special.fn$check_anon.invoke(fn.clj:31)
	at clojure.core.typed.check.special.fn$check_special_fn$fn__14110.invoke(fn.clj:206)
	at clojure.core.typed.check.special.fn$check_special_fn.invoke(fn.clj:199)
	at clojure.core.typed.check$fn__14797.invoke(check.clj:1364)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check.do$check_do.invoke(do.clj:21)
	at clojure.core.typed.check$check _COLON_do14821.doInvoke(check.clj:1382)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.MultiFn.invoke(MultiFn.java:227)
	at clojure.core.typed.check.def$check_normal_def.doInvoke(def.clj:61)
	at clojure.lang.RestFn.invoke(RestFn.java:442)
	at clojure.core.typed.check$check _COLON_def14956.doInvoke(check.clj:1673)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.MultiFn.invoke(MultiFn.java:231)
	at clojure.core.typed.check$check_expr.doInvoke(check.clj:150)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.core.typed.check$check_asts$iter__14184__14188$fn__14189$fn__14190.invoke(check.clj:119)
	at clojure.core.typed.check$check_asts$iter__14184__14188$fn__14189.invoke(check.clj:118)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.RT.seq(RT.java:484)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core$dorun.invoke(core.clj:2855)
	at clojure.core$doall.invoke(core.clj:2871)
	at clojure.core.typed.check$check_asts.invoke(check.clj:118)
	at clojure.core.typed.check.utils$check_ns_and_deps_STAR_.invoke(utils.clj:479)
	at clojure.core.typed.check$check_ns_and_deps.invoke(check.clj:130)
	at clojure.core.typed.check_ns_common$check_ns_info$fn__17011$fn__17012.invoke(check_ns_common.clj:82)
	at clojure.core.typed.check_ns_common$check_ns_info$fn__17011.invoke(check_ns_common.clj:58)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invoke(core.clj:624)
	at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.core.typed.check_ns_common$check_ns_info.doInvoke(check_ns_common.clj:44)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:628)
	at clojure.core.typed.check_ns_common$check_ns.doInvoke(check_ns_common.clj:112)
	at clojure.lang.RestFn.invoke(RestFn.java:425)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:628)
	at clojure.core.typed.check_ns_clj$check_ns.doInvoke(check_ns_clj.clj:23)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invoke(core.clj:626)
	at clojure.core.typed$fn__2034.doInvoke(typed.clj:2257)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at user$eval7$fn__8.invoke(form-init3689436395269879959.clj:1)
	at user$eval7.invoke(form-init3689436395269879959.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6703)
	at clojure.lang.Compiler.eval(Compiler.java:6693)
	at clojure.lang.Compiler.load(Compiler.java:7130)
	... 11 more
Subprocess failed
Comment by Ambrose Bonnaire-Sergeant [ 03/Dec/17 4:40 PM ]

Unsure how to proceed.

Comment by Jonathan Leonard [ 03/Dec/17 11:33 PM ]

Proceeding with a fix would obviously be my first choice.

Comment by Ambrose Bonnaire-Sergeant [ 04/Dec/17 7:07 AM ]

Agreed.

I had a vague idea yesterday to be able to override any annotation on a per-namespace granularity. Adding these kinds of annotations for namespaces you don't own seems a bit off at least.

This error message at least should be improved. I think it's overriding the default polymorphic annotation, which might break some internal invariants.





Generated at Tue Jan 16 04:04:04 CST 2018 using JIRA 4.4#649-r158309.