adds assert_with concept and uses it for get_completion_signatures an…#1815
adds assert_with concept and uses it for get_completion_signatures an…#1815kirkshoop wants to merge 1 commit intoNVIDIA:mainfrom
Conversation
…d connect diagnostics
|
i am interested in this. i need to do some experimentation with it first, and i'm on a hard deadline so it could be a while. but anyway...
nowhere in stdexec does any when i similarly misspell Truncated spew/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:211:22: note: candidate template ignored: constraints not satisfied [with _Sender = exec::__iterate::__sender<int *, int *>, _Receiver = exec::_seq::_rcvr<(anonymous
namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *, (anonymous namespace)::sum_receiver<>>>, true>, _DeclFn = __connect_declfn_t<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<std::execution::__env::env<>>>>, true>>]
211 | constexpr auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:209:18: note: because '__connectable_to<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<>>>, true>>' evaluated to false
209 | requires __connectable_to<_Sender, _Receiver>
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:57:58: note: because type constraint '__connect::__with_any_connect<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *,
int *, (anonymous namespace)::sum_receiver<>>>, true>>' was not satisfied:
57 | { transform_sender(__sndr(), get_env(__rcvr())) } -> __connect::__with_any_connect<_Receiver>;
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:49:34: note: because '__with_static_member<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<>>>, true>>' evaluated to false
49 | concept __with_any_connect = __with_static_member<_Sender, _Receiver>
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:33:44: note: because 'std::execution::__unref_t<_Sender>::static_connect(__sndr(), __rcvr())' would be invalid: no member named 'static_connect' in 'exec::__iterate::__sender<int *, int *>'
33 | STDEXEC_REMOVE_REFERENCE(_Sender)::static_connect(__sndr(), __rcvr());
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:50:34: note: and '__with_member<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<>>>, true>>' evaluated to false
50 | || __with_member<_Sender, _Receiver>
| ^
+/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:39:18: note: because '__sndr().connect(__rcvr())' would be invalid: no member named 'connect' in 'exec::__iterate::__sender<int *, int *>'
+ 39 | __sndr().connect(__rcvr());
+ | ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:51:34: note: and '__with_co_await<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<>>>, true>>' evaluated to false
51 | || __with_co_await<_Sender, _Receiver>
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:43:31: note: because '__awaitable<exec::__iterate::__sender<int *, int *>, __connect_await::__promise<exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<std::execution::__env::env<>>>>, true>>>' evaluated to false
43 | concept __with_co_await = __awaitable<_Sender, __connect_await::__promise<_Receiver>>;
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__awaitable.hpp:88:10: note: because type constraint '__awaiter<exec::__iterate::__sender<int *, int *> &&, std::execution::__connect_await::__promise<exec::_seq::_rcvr<(anonymous
namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *, (anonymous namespace)::sum_receiver<>>>, true>>>' was not satisfied:
88 | } -> __awaiter<_Promise...>;
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__awaitable.hpp:31:15: note: because '__awaiter.await_ready() ? 1 : 0' would be invalid: no member named 'await_ready' in 'exec::__iterate::__sender<int *, int *>'
31 | __awaiter.await_ready() ? 1 : 0;
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:52:34: note: and '__with_legacy_tag_invoke<exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<>>>, true>>' evaluated to false
52 | || __with_legacy_tag_invoke<_Sender, _Receiver>;
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__connect.hpp:46:40: note: because '__tag_invocable<connect_t, exec::__iterate::__sender<int *, int *>, exec::_seq::_rcvr<(anonymous namespace)::sum_item_rcvr<exec::__iterate::__next_receiver<int *, int *,
(anonymous namespace)::sum_receiver<>>>, true>>' evaluated to false
46 | concept __with_legacy_tag_invoke = __tag_invocable<connect_t, _Sender, _Receiver>;
| ^
/home/eniebler/Code/stdexec/include/exec/sequence/../../stdexec/__detail/__tag_invoke.hpp:32:7: note: because 'tag_invoke(static_cast<_Tag &&>(__tag), static_cast<_Args &&>(__args)...)' would be invalid: no matching function for call to 'tag_invoke'
32 | tag_invoke(static_cast<_Tag&&>(__tag), static_cast<_Args&&>(__args)...);
| ^
1 error generated.that is something i very much want to preserve, whatever we end up doing. |
Ok
What benefit does the compiler output for viability provide in the case of I think that printing the diagnostic during the My example did not use a sexpr sender, so it was not as clear that the existing |
I have tried quite hard to create a useful
__mexceptionwhen things fail and then coerce those into the result types of functions likeget_completion_signaturesandconnectand then to propagate them all the way through the layers.The recent changes have had me discard three previous attempts to prevent the actual error from being hidden by SFINAE and by
static_asserts that do not expand the problemsexprinto a form that is identifiable.This PR proposes a different approach. I have described this approach several times. Here it is in code.
With this PR -
Misspelling the name of this connect:
constexpr auto conNnect(_ItemRcvr __rcvr) const & noexcept(__nothrow_decay_copyable<_ItemRcvr>)Causes this test case:
TEST_CASE("iterate - sum up an array ", "[sequence_senders][iterate]") {To encounter a compile error while evaluating this line deep inside of the
iterate()sequence implementation:__optional<connect_result_t<__next_sender_t, __next_receiver_t>> __op_{};Which produces this log:
Notice that the
connectthat fails is far removed from the sequence'ssubscribe()and deeply buried inside the implementation ofiterate().Getting the failing
connectto create an__mexceptionand then propagating that as the result of thesubscribe()on the sequence returned fromiterate()is really hard to do the first time and unlikely to continue to work after each future change to the implementation ofiterate().This also allows trailing return types to be specified without causing SFINAE - as long as the
assert_withconstraints in the requires clause cover all the failure cases for computing the return type.NOTE: I removed a couple of tests because it appeared that they relied on
connect()SFINAE and they were now compile errors.