Commit 8a3d5b9c authored by Lewis Baker's avatar Lewis Baker Committed by Facebook GitHub Bot

Make sure coroutine final_suspend() methods are declared noexcept

Summary:
The C++20 specification for coroutines included a late change that
now requires the `co_await promise.final_suspend();` expression to
not be potentially throwing (ie. it needs to be declared `noexcept`).

This change updates all coroutine types in folly to make sure that
`final_suspend()` methods and the methods on awaitables returned from
these methods are all declared `noexcept` so that folly can be used
with compilers that enforce this requirement.

Reviewed By: yfeldblum

Differential Revision: D22203834

fbshipit-source-id: 4a5bbcbad644349d2ff0b08f6460fa13c3165aec
parent df45ceb8
......@@ -1445,7 +1445,7 @@ struct Promise {
std::experimental::suspend_never initial_suspend() const noexcept {
return {};
}
std::experimental::suspend_never final_suspend() const {
std::experimental::suspend_never final_suspend() const noexcept {
return {};
}
template <typename U>
......
......@@ -635,7 +635,7 @@ struct OptionalPromise {
std::experimental::suspend_never initial_suspend() const noexcept {
return {};
}
std::experimental::suspend_never final_suspend() const {
std::experimental::suspend_never final_suspend() const noexcept {
return {};
}
template <typename U>
......
......@@ -59,11 +59,11 @@ class ViaCoroutine {
*this)};
}
std::experimental::suspend_always initial_suspend() {
std::experimental::suspend_always initial_suspend() noexcept {
return {};
}
auto final_suspend() {
auto final_suspend() noexcept {
struct Awaiter {
bool await_ready() noexcept {
return false;
......
......@@ -38,11 +38,11 @@ class Wait {
return Wait(promise_.get_future());
}
std::experimental::suspend_never initial_suspend() {
std::experimental::suspend_never initial_suspend() noexcept {
return {};
}
std::experimental::suspend_never final_suspend() {
std::experimental::suspend_never final_suspend() noexcept {
return {};
}
......
......@@ -156,17 +156,17 @@ class DetachedBarrierTask {
auto final_suspend() noexcept {
struct awaiter {
bool await_ready() {
bool await_ready() noexcept {
return false;
}
auto await_suspend(
std::experimental::coroutine_handle<promise_type> h) {
std::experimental::coroutine_handle<promise_type> h) noexcept {
assert(h.promise().barrier_ != nullptr);
auto continuation = h.promise().barrier_->arrive();
h.destroy();
return continuation;
}
void await_resume() {}
void await_resume() noexcept {}
};
return awaiter{};
}
......
......@@ -254,21 +254,21 @@ inline InlineTask<void> InlineTaskPromise<void>::get_return_object() noexcept {
struct InlineTaskDetached {
class promise_type {
public:
InlineTaskDetached get_return_object() {
InlineTaskDetached get_return_object() noexcept {
return {};
}
std::experimental::suspend_never initial_suspend() {
std::experimental::suspend_never initial_suspend() noexcept {
return {};
}
std::experimental::suspend_never final_suspend() {
std::experimental::suspend_never final_suspend() noexcept {
return {};
}
void return_void() {}
void return_void() noexcept {}
[[noreturn]] void unhandled_exception() {
[[noreturn]] void unhandled_exception() noexcept {
std::terminate();
}
};
......
......@@ -28,11 +28,11 @@ class Wait {
return Wait(promise_.get_future());
}
std::experimental::suspend_never initial_suspend() {
std::experimental::suspend_never initial_suspend() noexcept {
return {};
}
std::experimental::suspend_never final_suspend() {
std::experimental::suspend_never final_suspend() noexcept {
return {};
}
......@@ -118,25 +118,20 @@ class InlineTask {
class FinalSuspender {
public:
explicit FinalSuspender(std::experimental::coroutine_handle<> awaiter)
: awaiter_(std::move(awaiter)) {}
bool await_ready() {
bool await_ready() noexcept {
return false;
}
void await_suspend(std::experimental::coroutine_handle<>) {
awaiter_();
auto await_suspend(
std::experimental::coroutine_handle<promise_type> h) noexcept {
return h.promise().awaiter_;
}
void await_resume() {}
private:
std::experimental::coroutine_handle<> awaiter_;
void await_resume() noexcept {}
};
FinalSuspender final_suspend() {
return FinalSuspender(std::move(awaiter_));
FinalSuspender final_suspend() noexcept {
return FinalSuspender{};
}
private:
......@@ -238,35 +233,30 @@ class InlineTaskAllocator {
*valuePtr_ = std::forward<U>(value);
}
void unhandled_exception() {
[[noreturn]] void unhandled_exception() noexcept {
std::terminate();
}
std::experimental::suspend_always initial_suspend() {
std::experimental::suspend_always initial_suspend() noexcept {
return {};
}
class FinalSuspender {
public:
explicit FinalSuspender(std::experimental::coroutine_handle<> awaiter)
: awaiter_(std::move(awaiter)) {}
bool await_ready() {
bool await_ready() noexcept {
return false;
}
void await_suspend(std::experimental::coroutine_handle<>) {
awaiter_();
auto await_suspend(
std::experimental::coroutine_handle<promise_type> h) noexcept {
return h.promise().awaiter_;
}
void await_resume() {}
private:
std::experimental::coroutine_handle<> awaiter_;
void await_resume() noexcept {}
};
FinalSuspender final_suspend() {
return FinalSuspender(std::move(awaiter_));
FinalSuspender final_suspend() noexcept {
return FinalSuspender{};
}
private:
......
......@@ -37,11 +37,11 @@ class Wait {
return Wait(promise_.get_future());
}
std::experimental::suspend_never initial_suspend() {
std::experimental::suspend_never initial_suspend() noexcept {
return {};
}
std::experimental::suspend_never final_suspend() {
std::experimental::suspend_never final_suspend() noexcept {
return {};
}
......@@ -127,24 +127,25 @@ class InlineTask {
class FinalSuspender {
public:
explicit FinalSuspender(std::experimental::coroutine_handle<> awaiter)
explicit FinalSuspender(
std::experimental::coroutine_handle<> awaiter) noexcept
: awaiter_(std::move(awaiter)) {}
bool await_ready() {
bool await_ready() noexcept {
return false;
}
auto await_suspend(std::experimental::coroutine_handle<>) {
auto await_suspend(std::experimental::coroutine_handle<>) noexcept {
return awaiter_;
}
void await_resume() {}
void await_resume() noexcept {}
private:
std::experimental::coroutine_handle<> awaiter_;
};
FinalSuspender final_suspend() {
FinalSuspender final_suspend() noexcept {
return FinalSuspender(std::move(awaiter_));
}
......
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