https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95345

            Bug ID: 95345
           Summary: Fold expressions don't work properly when pack
                    expression has co_await
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kacper.slominski72 at gmail dot com
  Target Milestone: ---

When compiling the following code with GCC 10.1.0 (and the trunk option on
Compiler Explorer but I don't know what commit that is) and these flags:
"-std=c++2a -fcoroutines -Wall -Wextra"

#include <coroutine>

struct dummy_coro {
        using promise_type = dummy_coro;
        bool await_ready() { return false; }
        void await_suspend(std::coroutine_handle<>) { }
        void await_resume() { }
        dummy_coro get_return_object() { return {}; }
        dummy_coro initial_suspend() { return {}; }
        dummy_coro final_suspend() { return {}; }
        void return_void() { }
        void unhandled_exception() { }
};

template <int ...I>
dummy_coro foo() {
        ((co_await [](int){ return std::suspend_never{}; }(I)), ...);
        co_return;
}

void bar() {
        foo<1>();
}

The compiler reports the following error:

<source>: In function 'dummy_coro foo()':
<source>:17:52: error: parameter packs not expanded with '...':
   17 |  ((co_await [](int){ return std::suspend_never{}; }(I)), ...);
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
<source>:17:52: note:         'I'
<source>:17:58: error: operand of fold expression has no unexpanded parameter
packs
   17 |  ((co_await [](int){ return std::suspend_never{}; }(I)), ...);
      |                                                          ^~~

The same code compiles without any issues with Clang 10.

Note that switching the order of the pack expression and ..., the error becomes
only:

<source>: In function 'dummy_coro foo()':
<source>:17:57: error: parameter packs not expanded with '...':
   17 |  (..., (co_await [](int){ return std::suspend_never{}; }(I)));
      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
<source>:17:57: note:         'I'

Also note that the dummy_coro type doesn't matter and is only shown for
completeness, and that the return type of the lambda in the pack expression
(which can also be a function call) also doesn't matter.

Reply via email to