<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Improper resolution of constraint requirements when using CRTP"
   href="https://bugs.llvm.org/show_bug.cgi?id=48074">48074</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Improper resolution of constraint requirements when using CRTP
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>11.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>barry.revzin@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Using libstdc++'s <ranges> header with clang 11 doesn't compile even the most
basic examples:

#include <ranges>
auto w = std::views::iota(0);

The failure reduces to the following:

template <typename T> T declval();

template <typename T> using begin_t = decltype(declval<T&>().begin());
template <typename T> concept C = true;

template <typename D>
struct simple_view_interface
{
    auto also_begin() requires
        #ifdef TYPE_TRAIT
        C<begin_t<D>>
        #else
        requires (D d) { {d.begin()} -> C; }
        #endif
    {
        return static_cast<D&>(*this).begin();
    }
};

struct wat_view : simple_view_interface<wat_view>
{
    auto begin() -> int* { return nullptr; }
};

auto w = wat_view().also_begin();

Both spellings of the requirement on also_begin() should be equivalent, and
should be valid in this case. The checking of the requirements should be
deferred until instantiation, at which point, wat_view is complete. 

If TYPE_TRAIT is defined, the requirement is eagerly instantiated, an even the
definition of wat_view fails to compile:

<source>:3:62: error: no member named 'begin' in 'wat_view'
template <typename T> using begin_t = decltype(declval<T&>().begin());
                                               ~~~~~~~~~~~~~ ^
<source>:11:11: note: in instantiation of template type alias 'begin_t'
requested here
        C<begin_t<D>>
          ^
<source>:20:19: note: in instantiation of template class
'simple_view_interface<wat_view>' requested here
struct wat_view : simple_view_interface<wat_view>
                  ^

If TYPE_TRAIT is not defined, wat_view is properly defined, but usage fails:

<source>:25:21: error: invalid reference to function 'also_begin': constraints
not satisfied
auto w = wat_view().also_begin();
                    ^
<source>:13:29: note: because 'd.begin()' would be invalid: no member named
'begin' in 'wat_view'
        requires (D d) { {d.begin()} -> C; }
                            ^

Even though there is a member named 'begin' in 'wat_view'.

The program should be valid either way. gcc accepts both.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>