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

            Bug ID: 99599
           Summary: Concepts requirement falsely reporting recursion,
                    breaks tag_invoke pattern
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: the_gamester28 at msn dot com
  Target Milestone: ---

The following code compiles fine on GCC 10, Clang, MSVC, but fails in GCC
11/trunk:

### begin

struct foo_tag{};
struct bar_tag{};

template <class T>
concept fooable = requires(T it) {
    invoke_tag(foo_tag{}, it); // <-- here
};

template<class T>
auto invoke_tag(foo_tag, T in) {
    return in;
}

template<fooable T>
auto invoke_tag(bar_tag, T it) {
    return it;
}

int main() {
    // Neither line below compiles in GCC 11, independently of the other
    return invoke_tag(foo_tag{}, 2);
    return invoke_tag(bar_tag{}, 2);
}

### end

Produces the following compiler error:

### begin

<source>: In substitution of 'template<class T>  requires  fooable<T> auto
invoke_tag(bar_tag, T) [with T = int]':
<source>:6:15:   required by substitution of 'template<class T>  requires 
fooable<T> auto invoke_tag(bar_tag, T) [with T = int]'
<source>:21:35:   required from here
<source>:5:9:   required for the satisfaction of 'fooable<T>' [with T = int]
<source>:5:19:   in requirements with 'T it' [with T = int]
<source>:5:19: error: satisfaction of atomic constraint 'requires(T it)
{invoke_tag({}, it);} [with T = T]' depends on itself
    5 | concept fooable = requires(T it) {
      |                   ^~~~~~~~~~~~~~~~
    6 |     invoke_tag(foo_tag{}, it);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    7 | };
      | ~                  

### end

It seems that the template requirements of invoke_tag(bar_tag, int) are
considered while evaluating line marked "here". Requirements of irrelevant
overloads should not be considered, as it can potentially lead to falsely
reporting a cyclic dependency.

This bug effectively prevents using the modern tag_invoke pattern, which is
increasingly used as a customisation point in many modern libraries.

Reply via email to