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