Hi,
I've just finished coding some async "cluster networking" prototype (using asyncnet), and I'm getting a compiler error that I don't undertand (don't know how to fix), while writing my first test module for it:
import asyncdispatch
import asyncnet
# ...
type
QueueID* = distinct uint32
Msg*[T: not (ref|string|seq)] = object
# ...
# ...
# Forward declaration:
proc sendMsgExternally[T](q: QueueID, m: ptr[Msg[T]], size: uint32) {.async.}
proc fillAndSendMsg[T](q: QueueID, m: ptr[Msg[T]], buffered: bool): void =
# ...
let size = uint32(sizeof(Msg[T]))
asyncCheck sendMsgExternally(q, m, size)
and on that last line, I am getting this error:
lib\pure\asyncmacro.nim(43, 27) Error: attempting to call undeclared routine: 'callback='
The content of sendMsgExternally() makes no difference; I replaced it with "discard", and the error stays. This is the only error I'm getting, so it's not a consequence of a previous error. Google was no help for this one.
Could you give some simplified example that can be ran? From the error message it's the line next.callback = (proc() {.closure, gcsafe.})(cb0) that gives the error.
Very likely the next object type doesn't have any defined proc with that or you missed some module (which I don't know which)
Also, is that ptr[Msg[T]] typo? Afaik, you should write it like this: ptr Msg[T]
If there is no obvious explanation, I'll try to create an example, but that file is way over 1000 lines now, so it will take some time.
Re "ptr[Msg[T]]", I alway write it like that; it never cause me trouble before. I prefer that syntax, because in Nim "type parameters" are normally added within [], and I see the type ptr is pointing to as a "type parameter" as well.
Try changing the forward declaration by replacing the async pragma with : Future[void].
Seems like an async macro bug.
@dom96 I tried your idea, and it didn't work. Then I changed the forward declaration to be a "normal" proc, and implemented it lower down to just delegate to the async proc (asyncCheck sendMsgExternally(...)), and it didn't work either. I'll try to build an example now. If it's an async macro bug, we need an example anyway, to open an issue about it.
EDIT: Hier is a reproducible example. If there is a work-around, I'd still like to know it, because it will probably take some time for the issue to be resolved, after it's posted to Github.
# modulea
import asyncdispatch
import asyncnet
type
QueueID* = uint32
Msg*[T: not (ref|string|seq)] = object
content*: T
proc myQueue*(): QueueID =
QueueID(0)
proc sendMsgInternally[T](q: QueueID, m: ptr[Msg[T]]): void =
echo("Sending message internally to " & $q)
proc sendMsgExternally[T](q: QueueID, m: ptr[Msg[T]], size: uint32) {.async.}
proc sendMsg*[T](q: QueueID, m: ptr[Msg[T]]): void =
# fill m with data ...
if q == myQueue():
sendMsgInternally(q, m)
else:
let size = uint32(sizeof(Msg[T]))
asyncCheck sendMsgExternally(q, m, size)
proc sendMsgExternally[T](q: QueueID, m: ptr[Msg[T]], size: uint32) {.async.} =
echo("Sending message across the cluster to " & $q)
var sock = newAsyncSocket()
await sock.send(pointer(m), int(size))
# moduleb
import modulea
type
TstMsg = Msg[int]
proc testIt() =
var m: TstMsg
m.content = 42
var dst = QueueID(99)
sendMsg(dst, addr m)
testIt()
And I get this error:
moduleb.nim(12, 10) template/generic instantiation from here
modulea.nim(25, 33) template/generic instantiation from here
lib\pure\asyncmacro.nim(43, 27) Error: attempting to call undeclared routine: 'callback='
Issue has been posted to Github.