https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97120
Bug ID: 97120
Summary: circular concept loops in <ranges>
Product: gcc
Version: 10.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: [email protected]
Target Milestone: ---
The following example compiles with gcc and fails with clang. I believe clang
is correct but can't prove it.
======= begin example =============
#include <ranges>
void foo() {
std::ranges::iota_view iota(2, 10);
iota.begin();
}
======== end example ==============
Clang complains that iota_view doesn't have a begin() member (which it does). I
think the reason is that the constraint is evaluated before iota_view is fully
defined. gcc evaluates lazily so it doesn't stumble on the problem.
The circular chain is:
view_interface<iota_view> is instantiated as a base class of iota_view. Clearly
iota_view isn't defined at this stage, it's just a forward-declared name.
view_interface instantiates iterator_t, which is an alias to
std::__detail::__range_iter_t.
__range_iter_t instantiates __ranges_begin.
__ranges_begin requires that its template parameter is a __member_begin<>
(among other options, but this is the valid one here).
__member_begin requires that the type (iota_view) have a begin() function. But
the type isn't defined yet.
I believe clang is correct, mostly because I believe concept evaluation should
be eager and not lazy, not because I know it for a fact.
Apologies for posting a clang issue here, I wouldn't if gcc could get
asan+coroutines working. The problem will hit gcc if it implements eager
evaluation too.