diff --git a/include/exec/libdispatch_queue.hpp b/include/exec/libdispatch_queue.hpp index e9ded94cb..24bf27221 100644 --- a/include/exec/libdispatch_queue.hpp +++ b/include/exec/libdispatch_queue.hpp @@ -537,7 +537,8 @@ namespace experimental::execution bulk_op_state(libdispatch_queue &queue, Shape shape, Fun fun, CvSender &&sndr, Receiver rcvr) : shared_state_(std::move(rcvr), shape, fun) - , inner_op_{STDEXEC::connect(std::move(sndr), bulk_rcvr{shared_state_, queue})} + , inner_op_{ + STDEXEC::connect(static_cast(sndr), bulk_rcvr{shared_state_, queue})} {} void start() & noexcept diff --git a/test/exec/test_libdispatch.cpp b/test/exec/test_libdispatch.cpp index 2f242b117..465411407 100644 --- a/test/exec/test_libdispatch.cpp +++ b/test/exec/test_libdispatch.cpp @@ -25,6 +25,42 @@ namespace { + struct lvalue_connect_sender + { + using sender_concept = STDEXEC::sender_tag; + + template + static consteval auto + get_completion_signatures() -> STDEXEC::completion_signatures + { + return {}; + } + + auto get_env() const noexcept -> STDEXEC::env<> + { + return {}; + } + + template + struct operation + { + using operation_state_concept = STDEXEC::operation_state_tag; + + Receiver receiver_; + + void start() & noexcept + { + STDEXEC::set_value(std::move(receiver_), 42); + } + }; + + template + auto connect(Receiver receiver) & noexcept -> operation + { + return {std::move(receiver)}; + } + }; + TEST_CASE("libdispatch queue should be able to process tasks") { exec::libdispatch_queue queue; @@ -201,4 +237,17 @@ namespace CHECK(seen == 42); CHECK_FALSE(value.moved_from); } + + TEST_CASE("libdispatch bulk connects an lvalue child sender as an lvalue") + { + exec::libdispatch_queue queue; + auto fun = [](int, int &) noexcept {}; + using sender_t = exec::__libdispatch::bulk_sender; + + sender_t sender{queue, lvalue_connect_sender{}, 0, std::move(fun)}; + auto result = STDEXEC::sync_wait(sender); + + REQUIRE(result.has_value()); + CHECK(std::get<0>(*result) == 42); + } } // namespace