macrosclojurecompilationcore.asyncmultimethod

core.async go block fails to compile when protocol invocation form contains <! macro (multimethod '-item-to-ssa' can't dispatch on :protocol-invoke)


I was implementing a function involving a core.async go block, when I stumbled on a strange compilation error :

CompilerException java.lang.IllegalArgumentException: 
No method in multimethod '-item-to-ssa' for dispatch value: :protocol-invoke, 
compiling:(NO_SOURCE_PATH:2:3) 

I experimented a little to try and strip down the problem, and found it was very generic. Say I have any protocol MyProtocol :

(defprotocol MyProtocol
  (do-something [this param] "some method"))

The following code will not compile, failing with the exception I showed you above :

(defn uncompilable! [me ch] 
  (go 
    (do-something me (<! ch)) ;; apparently, it hurts to use <! in a protocol method invocation 
    ))

However, the following 2 will compile without any problem :

(defn compilable! [me ch] 
  (let [call-it #(do-something me %)] ; wrapping the protocol call in a function
    (go 
     (call-it (<! ch))
     )))

(defn compilable-2! [me ch] 
  (go 
    (let [my-value (<! ch)] ; taking out the <! call
      (do-something me my-value))
    ))

Apparently, this has to do with the -item-to-ssa multimethod than can be found in the clojure.core.async.impl.ioc-macros namespace.

It seems to me the '<! inside protocol method invocation form' is a situation which the go macro fails to handle.

Does someone have an explanation about this? Should I file a bug?


This happened using [org.clojure/core.async "0.1.346.0-17112a-alpha"] and both [org.clojure/clojure "1.7.0-alpha1"] and [org.clojure/clojure "1.6.0"].

FYI, this happened when I was implementing a Ring-type middleware to marry http-kit async web server and core.async.


Solution

  • As Nathan Davis commented, this is fixed as of core.async 0.2.374.