ned14 / outcome

Provides very lightweight outcome<T> and result<T> (non-Boost edition)
https://ned14.github.io/outcome
Other
704 stars 62 forks source link

Coroutine final_suspend is not noexcept #236

Closed joemmett closed 4 years ago

joemmett commented 4 years ago

The final_suspend() functions and await_suspend() functions of the enclosed awaitable class are not noexcept in coroutine_support.ipp. The co_await expression for the final suspend point is required to be non-throwing by the standard.

The current implementation resumes the continuation (if there is one) in await_suspend(), so this is not necessarily quite just as simple as making it noexcept. Having await_suspend() return the continuation handle instead of directly resuming it would make it easier to make this noexcept.

ned14 commented 4 years ago

Nice catch, thanks!

ned14 commented 4 years ago

Can you look, and ideally, test f913c7e to see if it solves this? I don't have a compiler to hand able to test this code, so this patchset is pure guesswork.

joemmett commented 4 years ago

Thanks! I tried it out with a development branch build of MSVC and it's currently failing the coroutine test because lazy_await is directly using await_suspend and await_resume instead of co_awaiting it, so there is no compiler-generated resume of the returned handle. This trips the assertion that result_set has been set.

This could be solved with something like:

  auto lazy_await = [](auto t) {
#if OUTCOME_HAVE_NOOP_COROUTINE
    t.await_suspend({}).resume();
#else
    t.await_suspend({});
#endif
    return t.await_resume();
  };
ned14 commented 4 years ago

Ok, fixed as you suggest. Thanks for your help in fixing this!