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

Help compiler understand that co_yield co_error() in a Task coroutine never returns

Summary:
Mark the `await_resume()` method of the `final_suspend()` awaiter as `[[noreturn]]`.

This helps the compiler to dead-code eliminate this code, and in particular helps
the compiler to determine that code cannot continue execution after a
`co_yield co_error(ex)` expression (which calls `final_suspend()`).

This enables us to write code that has a `co_yield co_error()` statement as the
last line in a non-void `Task` coroutine without the compiler emitting a warning
about control running off the end of the coroutine.

Reviewed By: yfeldblum

Differential Revision: D22229020

fbshipit-source-id: b7a63b030cb42653198731d542ffa9bbf90daa83
parent ed2cb6d2
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#pragma once #pragma once
#include <exception>
#include <experimental/coroutine> #include <experimental/coroutine>
#include <type_traits> #include <type_traits>
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
#include <folly/experimental/coro/detail/Traits.h> #include <folly/experimental/coro/detail/Traits.h>
#include <folly/futures/Future.h> #include <folly/futures/Future.h>
#include <folly/io/async/Request.h> #include <folly/io/async/Request.h>
#include <folly/lang/Assume.h>
namespace folly { namespace folly {
namespace coro { namespace coro {
...@@ -65,7 +67,9 @@ class TaskPromiseBase { ...@@ -65,7 +67,9 @@ class TaskPromiseBase {
return promise.continuation_; return promise.continuation_;
} }
void await_resume() noexcept {} [[noreturn]] void await_resume() noexcept {
folly::assume_unreachable();
}
}; };
friend class FinalAwaiter; friend class FinalAwaiter;
......
...@@ -673,15 +673,17 @@ TEST(Coro, CoThrow) { ...@@ -673,15 +673,17 @@ TEST(Coro, CoThrow) {
EXPECT_THROW( EXPECT_THROW(
folly::coro::blockingWait([]() -> folly::coro::Task<int> { folly::coro::blockingWait([]() -> folly::coro::Task<int> {
co_yield folly::coro::co_error(ExpectedException()); co_yield folly::coro::co_error(ExpectedException());
EXPECT_TRUE(false) << "unreachable"; ADD_FAILURE() << "unreachable";
co_return 42; // Intential lack of co_return statement to check
// that compiler treats code after co_yield co_error()
// as unreachable.
}()), }()),
ExpectedException); ExpectedException);
EXPECT_THROW( EXPECT_THROW(
folly::coro::blockingWait([]() -> folly::coro::Task<void> { folly::coro::blockingWait([]() -> folly::coro::Task<void> {
co_yield folly::coro::co_error(ExpectedException()); co_yield folly::coro::co_error(ExpectedException());
EXPECT_TRUE(false) << "unreachable"; ADD_FAILURE() << "unreachable";
}()), }()),
ExpectedException); ExpectedException);
} }
......
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