Commit ddf4beb9 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

permit `co_return {};` in a coro::Task<T>-returning coroutine to default-construct a T

Summary: In a coroutine returning a `coro::Task<T>`, make `co_return {};` return a default-constructed `T` rather than a default-constructed `folly::Try`.

Reviewed By: yfeldblum, andriigrynenko

Differential Revision: D18466785

fbshipit-source-id: ed20f0f5ad98a0ef8e693e490417a7e36f706822
parent 67c9b092
...@@ -134,27 +134,21 @@ class TaskPromise : public TaskPromiseBase { ...@@ -134,27 +134,21 @@ class TaskPromise : public TaskPromiseBase {
exception_wrapper::from_exception_ptr(std::current_exception())); exception_wrapper::from_exception_ptr(std::current_exception()));
} }
template <typename U> void return_value(T&& t) {
void return_value(U&& value) { result_.emplace(static_cast<T&&>(t));
static_assert(
std::is_convertible<U&&, StorageType>::value,
"cannot convert return value to type T");
result_.emplace(static_cast<U&&>(value));
} }
void return_value(const Try<StorageType>& t) { template <typename U>
DCHECK(t.hasValue() || t.hasException()); void return_value(U&& value) {
result_ = t; if constexpr (std::is_same_v<remove_cvref_t<U>, Try<StorageType>>) {
} DCHECK(value.hasValue() || value.hasException());
result_ = static_cast<U&&>(value);
void return_value(Try<StorageType>& t) { } else {
DCHECK(t.hasValue() || t.hasException()); static_assert(
result_ = t; std::is_convertible<U&&, StorageType>::value,
} "cannot convert return value to type T");
result_.emplace(static_cast<U&&>(value));
void return_value(Try<StorageType>&& t) { }
DCHECK(t.hasValue() || t.hasException());
result_ = std::move(t);
} }
Try<StorageType>& result() { Try<StorageType>& result() {
......
...@@ -37,6 +37,14 @@ ...@@ -37,6 +37,14 @@
using namespace folly; using namespace folly;
struct S {
int x = 42;
};
coro::Task<S> taskS() {
co_return {};
}
coro::Task<int> task42() { coro::Task<int> task42() {
co_return 42; co_return 42;
} }
...@@ -557,4 +565,11 @@ TEST(Coro, CancellableSleep) { ...@@ -557,4 +565,11 @@ TEST(Coro, CancellableSleep) {
CHECK((end - start) < 1s); CHECK((end - start) < 1s);
} }
TEST(Coro, DefaultConstructible) {
coro::blockingWait([]() -> coro::Task<void> {
auto s = co_await taskS();
EXPECT_EQ(42, s.x);
}());
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment