clang ignores template functions for `co_await`?
Closed this issue · 2 comments
luncliff commented
branch : dev/net
Note
- https://github.com/luncliff/coroutine/blob/dev/net/interface/coroutine/net.h#L108
- https://travis-ci.org/luncliff/coroutine/jobs/528489726#L218
As the error message notes, it seems that co_await
operator searches only for member functions.
The following error is from clang 7.1.0 in WSL
clang version 7.1.0-svn353565-1~exp1~20190408084827.60 (branches/release_70)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
The message.
/mnt/d/coroutine/test/c2_socket_echo_tcp.cpp:139:20: error: no member named 'await_ready' in 'io_recv'
rsz = co_await recv_stream(sd, storage, 0, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_tcp.cpp:157:20: error: no member named 'await_ready' in 'io_send'
ssz = co_await send_stream(sd, storage, 0, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_tcp.cpp:176:20: error: no member named 'await_ready' in 'io_recv'
rsz = co_await recv_stream(sd, buf = storage, 0, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_udp.cpp:129:20: error: no member named 'await_ready' in 'io_recv_from'
rsz = co_await recv_from(sd, remote, storage, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_tcp.cpp:182:20: error: no member named 'await_ready' in 'io_send'
ssz = co_await send_stream(sd, buf, 0, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_udp.cpp:147:20: error: no member named 'await_ready' in 'io_send_to'
ssz = co_await send_to(sd, remote, storage, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_udp.cpp:164:24: error: no member named 'await_ready' in 'io_recv_from'
rsz = co_await recv_from(sd, remote, buf = storage, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/d/coroutine/test/c2_socket_echo_udp.cpp:168:24: error: no member named 'await_ready' in 'io_send_to'
ssz = co_await send_to(sd, remote, buf = {storage.data(), rsz}, work);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 errors generated.
make[2]: *** [test/CMakeFiles/coroutine_test.dir/c2_socket_echo_tcp.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
4 errors generated.
make[2]: *** [test/CMakeFiles/coroutine_test.dir/c2_socket_echo_udp.cpp.o] Error 1
make[1]: *** [test/CMakeFiles/coroutine_test.dir/all] Error 2
make: *** [all] Error 2
luncliff commented
Tried this, but this
handling can be complex.
//
// Derived class of `io_work_t` will be used for `co_await`.
// We can use template to generate functions for the operator
// and perform some type check for given types
//
// ToDo: C++ Concepts
//
template <typename IoStruct>
struct redirect_co_await {
// clang requires await_* functions to be the member function
// of the awaitable type. instead of defining those functions
// in each derived types, we will use this template
auto await_ready() noexcept {
static_assert(std::is_base_of_v<io_work_t, IoStruct>);
return this->ready();
}
// these functions is not the member of `io_work_t`.
// its derived type must declare/define it...
void await_suspend(io_task_t t) noexcept(false) {
static_assert(std::is_base_of_v<io_work_t, IoStruct>);
return this->suspend(t);
}
auto await_resume() noexcept {
static_assert(std::is_base_of_v<io_work_t, IoStruct>);
return this->resume();
}
};
// Type to perform `send` I/O request
class io_send final : public io_work_t, public redirect_co_await<io_send> {
public:
_INTERFACE_ void suspend(io_task_t t) noexcept(false);
_INTERFACE_ int64_t resume() noexcept;
};
static_assert(sizeof(io_send) == sizeof(io_work_t));
Performing rollback to the member function scheme...
luncliff commented
The standard document doesn't state that such an expression is possible.
I was confused with previous experiences...