summaryrefslogtreecommitdiffstats
path: root/library/cpp/threading/future
diff options
context:
space:
mode:
Diffstat (limited to 'library/cpp/threading/future')
-rw-r--r--library/cpp/threading/future/core/coroutine_traits.h5
-rw-r--r--library/cpp/threading/future/ut_gtest/coroutine_traits_ut.cpp7
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> {