Skip to content

Commit f016ebc

Browse files
snarkmasterfacebook-github-bot
authored andcommitted
Fix co_nothrow in now_task, add getErrorHandle support to TaskWrapper
Summary: Previously, `TaskWrapper` didn't support the `ExtendedCoroutineHandle` protocol called `getErrorHandle`, so `co_nothrow` had no effect in those coros. That is, `co_await co_nothrow()` would still throw. This adds a test for the broken behavior, fixes `TaskWrapper` to implement the protocol, which causes the test to pass. The new `if constexpr` branches in `await_transform` are covered by existing `NoexceptTest.cpp` coverage of `co_nothrow(noexceptAwaitable())`. Reviewed By: ispeters Differential Revision: D82927064 fbshipit-source-id: f5eb73d6cc97bcaadf2b1811f5d5d59d9af68ff6
1 parent fa28acf commit f016ebc

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

third-party/folly/src/folly/coro/TaskWrapper.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,16 @@ class TaskPromiseWrapperBase {
221221
auto& executorRef(TaskPromisePrivate tag) {
222222
return promise_.executorRef(tag);
223223
}
224+
225+
// These next two definitions forward `getErrorHandle` behavior to the
226+
// innermost promise object. See `ExtendedCoroutineHandle` for docs.
227+
228+
using use_extended_handle_concept = ExtendedCoroutineHandle::PrivateTag;
229+
230+
static ExtendedCoroutineHandle::PromiseBase* getPromiseBase(
231+
ExtendedCoroutineHandle::PrivateTag priv, TaskPromiseWrapperBase* me) {
232+
return Promise::getPromiseBase(priv, &me->promise_);
233+
}
224234
};
225235

226236
template <typename T, typename WrapperTask, typename Promise>

third-party/folly/src/folly/coro/safe/test/NowTaskTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,18 @@ CO_TEST(NowTaskTest, nothrow) {
208208
auto t = co_nothrow(demoNowTask(37));
209209
co_await std::move(t);
210210
#endif
211+
212+
// Check that the "nothrow" functionality still works
213+
struct MyErr : std::exception {};
214+
auto errTask = []() -> now_task<> { co_yield co_error{MyErr{}}; };
215+
auto outerTask = [&]() -> now_task<> {
216+
try {
217+
co_await co_nothrow(errTask());
218+
} catch (...) {
219+
ADD_FAILURE() << "Not reached";
220+
}
221+
};
222+
EXPECT_THROW(co_await outerTask(), MyErr);
211223
}
212224

213225
// `TryAwaitable` has a custom `operator co_await`, unlike `simple` and

0 commit comments

Comments
 (0)