Skip to content

Compilation error with GCC 10/11 due to coroutine + template function #449

@poor-circle

Description

@poor-circle

When compiling async_simple with GCC 10 or GCC 11, code that uses coroutines inside function templates triggers a spurious static_assert failure in Lazy.h, even though the usage is valid.This is a known compiler bug in GCC 10/11 related to how the promise type is deduced in coroutine functions under specific template patterns. The issue does not occur in GCC 12+, or Clang.

🔗 Minimal ReproductionGodbolt link: https://godbolt.org/z/oar1hbxTb

📄 Repro Code


#include "async_simple/coro/Lazy.h"

async_simple::coro::Lazy<void> foo();

// ✅ OK: template with type parameter

async_simple::coro::Lazy<void> bar_ok() {
    co_await foo();
}
async_simple::coro::Lazy<void> test_ok() {
    co_await bar_ok();
}

// ❌ FAILS on GCC 10/11: template with ONLY non-type parameter
template <int io>
async_simple::coro::Lazy<void> bar_err() {
    co_await foo();
}
async_simple::coro::Lazy<void> test_err() {
    co_await bar_err<0>();
}

❌ Error Message

.../async_simple/coro/Lazy.h:345:70: error: static assertion failed: 
'co_await Lazy' is only allowed to be called by Lazy or DetachedCoroutine
  345 |                 std::is_base_of<LazyPromiseBase, PromiseType>::value ||
      |                                                                ~~~~~~^~
  346 |                     std::is_same_v<detail::DetachedCoroutine::promise_type,
  347 |                                    PromiseType>,

The PromiseType is incorrectly inferred (or mangled) by GCC 10/11 due to GCC Bug #100673, causing the static_assert to fail even when the caller is a valid Lazy coroutine.
✅ Workarounds

  1. Remove template functions to normal functions on GCC 10/11.
  2. Upgrade to GCC ≥12 or use Clang;

💡 Suggested Improvement To improve user experience

Consider enhancing the static_assert message in Lazy.h for GCC 10/11 to include a hint about this known compiler issue, e.g.:'co_await Lazy' failed due to potential GCC 10/11 coroutine bug (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100673). Workaround: Remove template parameter, or upgrade to Clang/GCC 12+.
This would help users quickly identify and resolve the issue without deep debugging.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions