diff --git a/include/beman/execution/detail/let.hpp b/include/beman/execution/detail/let.hpp index 1158f933..499210af 100644 --- a/include/beman/execution/detail/let.hpp +++ b/include/beman/execution/detail/let.hpp @@ -167,7 +167,7 @@ struct impls_for<::beman::execution::detail::let_t> : ::beman::execu auto mkop{[&] { return ::beman::execution::connect( ::std::apply(::std::move(state.fun), - state.args.template emplace(::std::forward(args)...)), + ::std::move(state.args.template emplace(::std::forward(args)...))), let_receiver{receiver, state.env}); }}; ::beman::execution::start( diff --git a/tests/beman/execution/CMakeLists.txt b/tests/beman/execution/CMakeLists.txt index 696ec350..00b1683f 100644 --- a/tests/beman/execution/CMakeLists.txt +++ b/tests/beman/execution/CMakeLists.txt @@ -13,6 +13,7 @@ list( APPEND execution_tests issue-174.test + issue-186.test exec-scope-counting.test exec-spawn.test exec-stop-when.test diff --git a/tests/beman/execution/issue-186.test.cpp b/tests/beman/execution/issue-186.test.cpp new file mode 100644 index 00000000..fcb4972f --- /dev/null +++ b/tests/beman/execution/issue-186.test.cpp @@ -0,0 +1,34 @@ +#include +#include + +namespace ex = beman::execution; + +namespace { +struct move_only_type { + move_only_type() : val(0) {} + explicit move_only_type(int v) : val(v) {} + ~move_only_type() = default; + + move_only_type(const move_only_type&) = delete; + move_only_type& operator=(const move_only_type&) = delete; + + move_only_type& operator=(move_only_type&&) = default; + move_only_type(move_only_type&&) = default; + int val; // NOLINT +}; +} // namespace + +int main() { + auto snd = ex::just(move_only_type(1)) // + | ex::then([](move_only_type v) noexcept { return v.val * 2; }) // + | ex::let_value([](int v) noexcept { return ex::just(v * 3); }); // int + auto [ret] = ex::sync_wait(std::move(snd)).value(); + assert(ret == 6); + + // NOTE: Compile time error with move_only_type + auto snd2 = ex::just(move_only_type(1)) // + | ex::then([](move_only_type v) noexcept { return move_only_type{v.val * 2}; }) // + | ex::let_value([](move_only_type v) noexcept { return ex::just(v.val * 3); }); // move_only_type + auto [ret2] = ex::sync_wait(std::move(snd2)).value(); + assert(ret2 == 6); +}