Bug 97120 - circular concept loops in <ranges>
Summary: circular concept loops in <ranges>
Status: RESOLVED MOVED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 10.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2020-09-19 15:34 UTC by Avi Kivity
Modified: 2021-11-23 17:05 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Avi Kivity 2020-09-19 15:34:08 UTC
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.
Comment 1 TC 2020-09-19 23:26:56 UTC
Concept evaluation is lazy, not eager. See [temp.inst]/18.
Comment 2 Avi Kivity 2020-09-20 05:27:38 UTC
This makes sense, according to my very limited ability to understand the standard. I reflected it to the clang bug here: https://bugs.llvm.org/show_bug.cgi?id=47509.
Comment 3 Jonathan Wakely 2021-11-23 17:05:12 UTC
This is a clang bug.