Does the C++20 standard allow mixing co_await and return with if constexpr discarded statements?

60 Views Asked by At

If I have code of the following form, which uses if constexpr to conditionally implement a coroutine directly or to dispatch to another function:

Task<void> SomeVoidCoroutine();

template <int N>
Task<void> TemplatedCoroutine() {
  if constexpr (N != 0) {
    // Call SomeVoidCoroutine twice.
    co_await SomeVoidCoroutine();
    co_await SomeVoidCoroutine();
    co_return;
  } else {
    // We only need to call it once, so we can just do a tail call.
    return SomeVoidCoroutine();
  }
}

then clang tells me off for mixing co_await and return in the same function:

foo.h:95:5: error: return statement not allowed in coroutine; did you mean 'co_return'?
    return SomeVoidCoroutine();
    ^
foo.h:90:5: note: function is a coroutine due to use of 'co_await' here
    co_await SomeVoidCoroutine();
    ^

This is despite the fact one side of the if constexpr is always discarded, so only one of the two keywords is "active" for any given template instantiation.

I can see why this would be an error, but I could also imagine it's just an implementation shortcoming in clang. My question is: does the standard say whether it's okay to use return in a function that would be a coroutine if it weren't for a discarded statement? I can see where the standard discusses discarded statements and where it defines what a coroutine is, but I'm not sure where the requirement not to mix the keywords is so I'm not sure how to answer this question.

0

There are 0 best solutions below