diff options
Diffstat (limited to 'library/cpp/threading/future')
| -rw-r--r-- | library/cpp/threading/future/core/coroutine_traits.h | 5 | ||||
| -rw-r--r-- | library/cpp/threading/future/ut_gtest/coroutine_traits_ut.cpp | 7 |
2 files changed, 11 insertions, 1 deletions
diff --git a/library/cpp/threading/future/core/coroutine_traits.h b/library/cpp/threading/future/core/coroutine_traits.h index b36362db28a..9ad791e58d0 100644 --- a/library/cpp/threading/future/core/coroutine_traits.h +++ b/library/cpp/threading/future/core/coroutine_traits.h @@ -87,6 +87,11 @@ struct std::coroutine_traits<NThreading::TFuture<T>, Args...> { Y_ASSERT(success && "value already set"); } + // Allow only rvalues to be returned to prevent slicing + template <typename E> + requires std::derived_from<std::remove_cvref_t<E>, std::exception> + void return_value(E& err) = delete; + void return_value(auto&& val) { bool success = State_->TrySetValue(std::forward<decltype(val)>(val), /* deferCallbacks */ true); Y_ASSERT(success && "value already set"); diff --git a/library/cpp/threading/future/ut_gtest/coroutine_traits_ut.cpp b/library/cpp/threading/future/ut_gtest/coroutine_traits_ut.cpp index a9b0176920e..0f902b9b998 100644 --- a/library/cpp/threading/future/ut_gtest/coroutine_traits_ut.cpp +++ b/library/cpp/threading/future/ut_gtest/coroutine_traits_ut.cpp @@ -149,7 +149,12 @@ TEST(TestFutureTraits, ErrorViaReturnException) { co_return std::runtime_error("exception_to_return"); static std::runtime_error another("another_exception_not_to_return"); - co_return another; + + // should not compile + // co_return another; + + // explicit slicing is allowed + co_return std::exception(another); }; auto coroutineReturnValueReturnException = [&]() -> NThreading::TFuture<size_t> { |
