diff --git a/include/stdexec/__detail/__write_env.hpp b/include/stdexec/__detail/__write_env.hpp index 011656c20..8e7614cbc 100644 --- a/include/stdexec/__detail/__write_env.hpp +++ b/include/stdexec/__detail/__write_env.hpp @@ -61,10 +61,10 @@ namespace stdexec { stdexec::get_env(__child)); }; - static constexpr auto get_env = - [](__ignore, const auto& __state, const auto& __rcvr) noexcept { - return __env::__join(__state, stdexec::get_env(__rcvr)); - }; + static constexpr auto get_env = [](__ignore, const auto& __state, const auto& __rcvr) noexcept + -> decltype(__env::__join(__state, stdexec::get_env(__rcvr))) { + return __env::__join(__state, stdexec::get_env(__rcvr)); + }; static constexpr auto get_completion_signatures = [](_Self &&, _Env &&...) noexcept diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b3f8113cf..a761a079e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -55,6 +55,7 @@ set(stdexec_test_sources stdexec/algos/adaptors/test_stopped_as_optional.cpp stdexec/algos/adaptors/test_stopped_as_error.cpp stdexec/algos/adaptors/test_ensure_started.cpp + stdexec/algos/adaptors/test_write_env.cpp stdexec/algos/consumers/test_start_detached.cpp stdexec/algos/consumers/test_sync_wait.cpp stdexec/algos/other/test_execute.cpp diff --git a/test/stdexec/algos/adaptors/test_write_env.cpp b/test/stdexec/algos/adaptors/test_write_env.cpp new file mode 100644 index 000000000..c31c1c10b --- /dev/null +++ b/test/stdexec/algos/adaptors/test_write_env.cpp @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2025 Robert Leahy. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + * Licensed under the Apache License, Version 2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include +#include + +namespace { + + template + struct receiver : expect_void_receiver<> { + constexpr ::stdexec::env<> get_env() const noexcept { + return state_->get_env(); + } + T* state_; + }; + + struct state; + + static_assert(!std::is_same_v< + void, + decltype(::stdexec::connect( + ::stdexec::just() + | ::stdexec::write_env(::stdexec::prop{ + ::stdexec::get_stop_token, + std::declval<::stdexec::inplace_stop_source&>().get_token()}), + receiver{{}, nullptr}))>); + + struct state { + constexpr ::stdexec::env<> get_env() const noexcept { + return {}; + } + }; + + TEST_CASE( + "write_env works when the actual environment is sourced from a type which was initially " + "incomplete but has since been completed", + "[adaptors][write_env]") { + ::stdexec::inplace_stop_source source; + state s; + auto op = ::stdexec::connect( + ::stdexec::just() + | ::stdexec::write_env(::stdexec::prop{::stdexec::get_stop_token, source.get_token()}), + receiver{{}, &s}); + ::stdexec::start(op); + } +} // namespace