3rdparty/eventuals

Better compiler error messages when assigning incompatible `Tasks`

Opened this issue · 0 comments

This compiles just fine:

#include <memory>
#include <string>

#include "eventuals/grpc/client.h"
#include "eventuals/grpc/completion-pool.h"
#include "eventuals/task.h"
#include "eventuals/then.h"
#include "grpcpp/security/credentials.h"
#include "stout/borrowed_ptr.h"

::eventuals::Task::Of<void>::With<::eventuals::grpc::Client> my_method(
    const std::string& target,
    const std::shared_ptr<::grpc::ChannelCredentials>& credentials,
    stout::borrowed_ptr<::eventuals::grpc::CompletionPool> pool) {
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
      ::eventuals::grpc::Client(target, credentials, std::move(pool)),
      [](::eventuals::grpc::Client& client) {
        return ::eventuals::Then([]() {});
      });
}

But if you drop the ::With<> bit from the return type:

#include <memory>
#include <string>

#include "eventuals/grpc/client.h"
#include "eventuals/grpc/completion-pool.h"
#include "eventuals/task.h"
#include "eventuals/then.h"
#include "grpcpp/security/credentials.h"
#include "stout/borrowed_ptr.h"

::eventuals::Task::Of<void> my_method(  // Different return type!
    const std::string& target,
    const std::shared_ptr<::grpc::ChannelCredentials>& credentials,
    stout::borrowed_ptr<::eventuals::grpc::CompletionPool> pool) {
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
      ::eventuals::grpc::Client(target, credentials, std::move(pool)),
      [](::eventuals::grpc::Client& client) {
        return ::eventuals::Then([]() {});
      });
}

It fails to compile with an error that's very difficult to understand, complaining about bad callables and lambdas being too large for a callback:


In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:329:7: error: static_assert failed due to requirement 'std::is_invocable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>::value' "'Task' expects a callable (e.g., a lambda) that takes no arguments"
      static_assert(
      ^
external/com_github_3rdparty_eventuals/eventuals/task.h:511:7: note: in instantiation of function template specialization 'eventuals::_TaskFromToWith::Composable<void, void, std::tuple<>>::Composable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
    : e_(std::move(args)..., std::move(f)) {}
      ^
respect/keep_alive/keep_alive_rpc_handler.cc:15:10: note: in instantiation of function template specialization 'eventuals::_Task<void, void, std::tuple<>>::_Task<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
         ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:350:7: error: static_assert failed due to requirement 'sizeof (f) <= SIZEOF_CALLBACK' "'Task' expects a callable (e.g., a lambda) that can be captured in a 'Callback'"
      static_assert(
      ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:1:
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/memory:76:
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/unique_ptr.h:37:
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/tuple:1858:14: error: no matching function for call to '__invoke'
      return std::__invoke(std::forward<_Fn>(__f),
             ^~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/tuple:1869:19: note: in instantiation of function template specialization 'std::__apply_impl<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client> &, std::tuple<> &>' requested here
      return std::__apply_impl(std::forward<_Fn>(__f),
                  ^
external/com_github_3rdparty_eventuals/eventuals/task.h:355:31: note: in instantiation of function template specialization 'std::apply<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client> &, std::tuple<> &>' requested here
      using E = decltype(std::apply(f, args_));
                              ^
external/com_github_3rdparty_eventuals/eventuals/task.h:511:7: note: in instantiation of function template specialization 'eventuals::_TaskFromToWith::Composable<void, void, std::tuple<>>::Composable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
    : e_(std::move(args)..., std::move(f)) {}
      ^
respect/keep_alive/keep_alive_rpc_handler.cc:15:10: note: in instantiation of function template specialization 'eventuals::_Task<void, void, std::tuple<>>::_Task<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
         ^
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:90:5: note: candidate template ignored: substitution failure [with _Callable = eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client> &, _Args = <>]: no type named 'type' in 'std::__invoke_result<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client> &>'
    __invoke(_Callable&& __fn, _Args&&... __args)
    ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:357:7: error: static_assert failed due to requirement 'std::is_void_v<int> || HasValueFrom<int, void>::value' "'Task' expects a callable (e.g., a lambda) that returns an eventual but you're returning a value"
      static_assert(
      ^
external/com_github_3rdparty_eventuals/eventuals/task.h:511:7: note: in instantiation of function template specialization 'eventuals::_TaskFromToWith::Composable<void, void, std::tuple<>>::Composable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
    : e_(std::move(args)..., std::move(f)) {}
      ^
respect/keep_alive/keep_alive_rpc_handler.cc:15:10: note: in instantiation of function template specialization 'eventuals::_Task<void, void, std::tuple<>>::_Task<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
         ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:371:7: error: static_assert failed due to requirement 'tuple_types_subset_subtype_v<int, std::tuple<>>' "Specified errors can't be raised within 'Task'"
      static_assert(
      ^
external/com_github_3rdparty_eventuals/eventuals/task.h:375:7: error: static_assert failed due to requirement 'std::disjunction_v<std::is_same<int, eventuals::_TaskFailure>, std::is_convertible<int, void>>' "eventual result type can not be converted into type of 'Task'"
      static_assert(
      ^
external/com_github_3rdparty_eventuals/eventuals/task.h:393:43: error: type 'typename std::remove_reference<_Task<void, void, tuple<>, Client> &>::type' (aka 'eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>') does not provide a call operator
              new HeapTask<E, From_, To_>(f(args...)),
                                          ^
external/com_github_3rdparty_eventuals/eventuals/task.h:127:47: error: member reference base type 'int' is not a structure or union
  using Adapted_ = decltype(std::declval<E_>().template k<From_>(
                            ~~~~~~~~~~~~~~~~~~^         ~
external/com_github_3rdparty_eventuals/eventuals/task.h:403:14: note: in instantiation of template class 'eventuals::HeapTask<int, void, void>' requested here
            e->Start(
             ^
external/com_github_3rdparty_eventuals/eventuals/task.h:511:7: note: in instantiation of function template specialization 'eventuals::_TaskFromToWith::Composable<void, void, std::tuple<>>::Composable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
    : e_(std::move(args)..., std::move(f)) {}
      ^
respect/keep_alive/keep_alive_rpc_handler.cc:15:10: note: in instantiation of function template specialization 'eventuals::_Task<void, void, std::tuple<>>::_Task<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
         ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:102:13: error: member reference base type 'eventuals::HeapTask<int, void, void>::Adapted_' (aka 'int') is not a structure or union
    adapted_.Register(interrupt);
    ~~~~~~~~^~~~~~~~~
external/com_github_3rdparty_eventuals/eventuals/task.h:411:16: note: in instantiation of member function 'eventuals::HeapTask<int, void, void>::Fail' requested here
            e->Fail(
               ^
external/com_github_3rdparty_eventuals/eventuals/task.h:511:7: note: in instantiation of function template specialization 'eventuals::_TaskFromToWith::Composable<void, void, std::tuple<>>::Composable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
    : e_(std::move(args)..., std::move(f)) {}
      ^
respect/keep_alive/keep_alive_rpc_handler.cc:15:10: note: in instantiation of function template specialization 'eventuals::_Task<void, void, std::tuple<>>::_Task<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
         ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:104:13: error: member reference base type 'eventuals::HeapTask<int, void, void>::Adapted_' (aka 'int') is not a structure or union
    adapted_.Fail(std::move(exception));
    ~~~~~~~~^~~~~
external/com_github_3rdparty_eventuals/eventuals/task.h:118:13: error: member reference base type 'eventuals::HeapTask<int, void, void>::Adapted_' (aka 'int') is not a structure or union
    adapted_.Register(interrupt);
    ~~~~~~~~^~~~~~~~~
external/com_github_3rdparty_eventuals/eventuals/task.h:419:16: note: in instantiation of member function 'eventuals::HeapTask<int, void, void>::Stop' requested here
            e->Stop(
               ^
external/com_github_3rdparty_eventuals/eventuals/task.h:511:7: note: in instantiation of function template specialization 'eventuals::_TaskFromToWith::Composable<void, void, std::tuple<>>::Composable<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
    : e_(std::move(args)..., std::move(f)) {}
      ^
respect/keep_alive/keep_alive_rpc_handler.cc:15:10: note: in instantiation of function template specialization 'eventuals::_Task<void, void, std::tuple<>>::_Task<eventuals::_Task<void, void, std::tuple<>, eventuals::grpc::Client>>' requested here
  return ::eventuals::Task::Of<void>::With<::eventuals::grpc::Client>(
         ^
In file included from respect/keep_alive/keep_alive_rpc_handler.cc:6:
external/com_github_3rdparty_eventuals/eventuals/task.h:120:13: error: member reference base type 'eventuals::HeapTask<int, void, void>::Adapted_' (aka 'int') is not a structure or union
    adapted_.Stop();
    ~~~~~~~~^~~~~

It would be much better to instead return an error like "Can't assign A to B", or "No overload of operator=() found".