Regression in rpc(team,rank,..,view) overload resolution leads to confusing type errors
Example program:
#include <upcxx/upcxx.hpp>
#include <iostream>
using namespace upcxx;
int main() {
upcxx::init();
constexpr int N = 100;
char A[N];
auto myview = make_view(A, A+N);
{
auto f = rpc(0, [](view<char> const &){}, myview);
f.wait();
}
{
auto f = rpc(world(), 0, [](view<char> const &){}, myview);
f.wait();
}
upcxx::finalize();
return 0;
}
Typechecking for this simple program has broken as of release 2020.10.0 (and also 2020.11.0), leading to overload resolution errors (eg gcc 10.2.0):
rpc-overload.cpp: In function 'int main()':
rpc-overload.cpp:19:62: error: call of overloaded 'rpc(upcxx::team&, int, main()::<lambda(const upcxx::view<char, char*>&)>, upcxx::view<char, char*>&)' is ambiguous
19 | auto f = rpc(world(), 0, [](view<char> const &){}, myview);
| ^
In file included from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/dist_object.hpp:7,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/upcxx.hpp:12,
from rpc-overload.cpp:1:
/usr/local/pkg/upcxx-dirac/gcc-10.2.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/rpc.hpp:480:8: note: candidate: 'typename std::enable_if<(! upcxx::detail::is_completions<Fn>::value), typename upcxx::detail::rpc_return_no_sfinae<Fn(Arg ...), upcxx::completions<upcxx::future_cx<upcxx::operation_cx_event, upcxx::progress_level::user> > >::type>::type upcxx::rpc(const upcxx::team&, upcxx::intrank_t, Fn&&, Arg&& ...) [with Fn = main()::<lambda(const upcxx::view<char, char*>&)>; Arg = {upcxx::view<char, char*>&}; typename std::enable_if<(! upcxx::detail::is_completions<Fn>::value), typename upcxx::detail::rpc_return_no_sfinae<Fn(Arg ...), upcxx::completions<upcxx::future_cx<upcxx::operation_cx_event, upcxx::progress_level::user> > >::type>::type = upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general> >; upcxx::intrank_t = int]'
480 | auto rpc(const team &tm, intrank_t recipient, Fn &&fn, Arg &&...args)
| ^~~
/usr/local/pkg/upcxx-dirac/gcc-10.2.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/rpc.hpp:421:14: note: candidate: 'upcxx::future<> upcxx::detail::rpc(const upcxx::team&, upcxx::intrank_t, Fn&&, Arg&& ..., Cxs&&, ...) [with Cxs = upcxx::view<char, char*>&; Fn = main()::<lambda(const upcxx::view<char, char*>&)>; Arg = {}; upcxx::future<> = upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general> >; upcxx::intrank_t = int]'
421 | future<> rpc(const team &, intrank_t, Fn &&, Arg &&..., Cxs&&, ...) {
| ^~~
and/or spurious static assertions (eg clang 11.0):
In file included from rpc-overload.cpp:1:
In file included from /usr/local/pkg/upcxx-dirac/clang-11.0.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/upcxx.hpp:12:
In file included from /usr/local/pkg/upcxx-dirac/clang-11.0.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/dist_object.hpp:7:
/usr/local/pkg/upcxx-dirac/clang-11.0.0/stable-2020.10.0/upcxx.debug.gasnet_seq.ibv/include/upcxx/rpc.hpp:429:7: error: static_assert failed due to requirement 'detail::rpc_return_no_sfinae<(lambda at rpc-overload.cpp:19:30) (), upcxx::view<char, char *>, void>::value' "function object provided to rpc cannot be invoked on the given arguments as rvalue references (after deserialization of the function object and arguments). Note: make sure that the function object does not have any non-const lvalue-reference parameters."
static_assert(
^
rpc-overload.cpp:19:14: note: in instantiation of function template specialization 'upcxx::detail::rpc<upcxx::view<char, char *> &, (lambda at rpc-overload.cpp:19:30)>' requested here
auto f = rpc(world(), 0, [](view<char> const &){}, myview);
^
1 error generated.
The problem is the unqualified call to rpc(team, rank, ...)
is being resolved ambiguously due to an incorrectly/inadvertently included internal function overload detail::rpc
(which appears to get pulled in via ADL on the view
argument).
The recommended workaround for users is to explicitly qualify the problematic call with a namespace (ie upcxx::rpc(...)
).
Comments (2)
-
reporter -
reporter - changed status to resolved
issue
#428: Regression inrpc(team,rank,..,view)
overload resolution leads to confusing type errorsName-shift the internal function names in the
detail
namespace, improving readability and guaranteeing they will never participate in overload resolution for the public API.Fixes issue
#428→ <<cset 882a442b044f>>
- Log in to comment
Proposed solution in pull request #298