<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/115975>115975</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Improve compiler errors when things like `std::ranges::range()` are not satisfied
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          zetafunction
      </td>
    </tr>
</table>

<pre>
    Consider a snippet like:

```
#include <ranges>
#include <vector>

class UnsizedVector {
 public:
 // Sentinel iterator type that wraps `end()` to ensure this type doesn't
 // satisfy the `sized_range` concept.
  template <typename Iterator>
 class Sentinel {
   public:
    explicit Sentinel(Iterator it) : wrapped_it_(it) {}

    bool operator==(Iterator it) { return wrapped_it_ == it; }

   private:
    Iterator wrapped_it_;
 };

  auto begin() const { return v_.begin(); }
  auto end() const { return Sentinel(v_.end()); }

 private:
  std::vector<int> v_;
};

static_assert(std::ranges::range<UnsizedVector>);
```
godbolt: https://godbolt.org/z/WoWYrhnGE

This produces:
```
<source>:26:15: error: static assertion failed
   26 | static_assert(std::ranges::range<UnsizedVector>);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:26:15: note: because 'UnsizedVector' does not satisfy 'range'
/opt/compiler-explorer/clang-trunk-20241112/bin/../include/c++/v1/__ranges/concepts.h:49:3: note: because 'ranges::end(__t)' would be invalid: call to deleted function call operator in type 'const __end::__fn'
   49 |   ranges::end(__t);
 |   ^
1 error generated.
Compiler returned: 1
```

But this isn't actually a useful error.

The actual constraint that's failing here is `std::sentinel_for<ranges::iterator_t<T>>`, and if you manually `static_assert`, then the error(s) become much clearer:
```
<source>:26:15: error: static assertion failed
   26 | static_assert(std::ranges::range<UnsizedVector>);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:26:15: note: because 'UnsizedVector' does not satisfy 'range'
/opt/compiler-explorer/clang-trunk-20241112/bin/../include/c++/v1/__ranges/concepts.h:49:3: note: because 'ranges::end(__t)' would be invalid: call to deleted function call operator in type 'const __end::__fn'
   49 |   ranges::end(__t);
 |   ^
<source>:27:15: error: static assertion failed
   27 | static_assert(std::sentinel_for<UnsizedVector::Sentinel<std::vector<int>::iterator>, std::vector<int>::iterator>);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:15: note: because 'std::sentinel_for<UnsizedVector::Sentinel<std::vector<int>::iterator>, std::vector<int>::iterator>' evaluated to false
/opt/compiler-explorer/clang-trunk-20241112/bin/../include/c++/v1/__iterator/concepts.h:139:24: note: because 'UnsizedVector::Sentinel<std::__wrap_iter<int *>>' does not satisfy 'semiregular'
  139 | concept sentinel_for = semiregular<_Sp> && input_or_output_iterator<_Ip> && __weakly_equality_comparable_with<_Sp, _Ip>;
      | ^
/opt/compiler-explorer/clang-trunk-20241112/bin/../include/c++/v1/__concepts/semiregular.h:27:40: note: because 'UnsizedVector::Sentinel<std::__wrap_iter<int *>>' does not satisfy 'default_initializable'
   27 | concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
      | ^
/opt/compiler-explorer/clang-trunk-20241112/bin/../include/c++/v1/__concepts/constructible.h:35:33: note: because 'UnsizedVector::Sentinel<std::__wrap_iter<int *>>' does not satisfy 'constructible_from'
   35 | concept default_initializable = constructible_from<_Tp> && requires { _Tp{}; } && __default_initializable<_Tp>;
      | ^
/opt/compiler-explorer/clang-trunk-20241112/bin/../include/c++/v1/__concepts/constructible.h:27:51: note: because 'is_constructible_v<UnsizedVector::Sentinel<std::__wrap_iter<int *> > >' evaluated to false
   27 | concept constructible_from = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
      | ^
2 errors generated.
Compiler returned: 1
```
godbolt: https://godbolt.org/z/E7sdEdWTY

The compiler diagnostics would be significantly more helpful if the compiler highlighted the failing constraint here, rather than just telling me that `end()` is a deleted function.

FWIW, gcc doesn't do a lot better here; it just tells me to keep increasing the number I pass to `-fconcepts-diagnostics-depth=`, but it also highlights a bunch of irrelevant stuff :)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEuT4jgS_jXiklEElgHDgQNFFRt1nt6tmJNDttO2poXk0YNa-rC_fUPyA_Oamp3Z3p2JGIKmC5xKfZn55SenmTG8kogbsngmi5cJc7ZWevMNLSudzC1XcpKp4rTZKWl4gRoYGMmbBi0I_hVJvCWzFzLrP5ez7t1-pTGXuXAFAol3mskKDYlf7108Ym6VPl8Mn7lgxsDfpeHfsPhHsACSPLcXoXGZ4PmAAAjdE7qHH1BaLlEAt6iZX2JPDYKtmYUPzRoDZDlDWRC6InRNljOwClAap70RN615odBIQhN76dwwy015AlujdxOApSEw7yhXMsfGTrs1YPHQCGZDgN6rZAeEtw7WECu0YQ64zxHCTYwAgP9sBM-5HRYQuup9AreEroHE2xBqg0XKbUroqvs9eSbJyzjD3mGmlADV9Khe_PvWZfIMGq3TcuwZWnNvEz_Dre9G8yOzeIF_cDxGGPchex_9l34Nc1ZBhhWXbc18no0dQzqm09H1Cyzd8qHgt4tHeTym0zMzrhz1rLsJydjCf4u3PYd3XFoSv8LxHNdtWMYyy_OUGYPaEroavPRtMvxN4t1FC3jiBGx3e65SRaaE9RSorW2Co8Dd7sJU6YrQ_TdC9-_q_Uddy79d9NwX3wKNVoXLWxR3GzveGeV0jh5LvKVLEm-jhd8TtfYIt9DGB218XEkoGRdYDDygSyDJDv5raYDw8i7J4vVfn7w-i0KqUGHIMGfOIBCaXO5Nk6AQ3nDQBEKTFihNeoXbq8YSus_VoeEC9ZPvXaVR-98Ek9WT1U5-faIzOo-iiBK6zzyJ99MpoftOHb0toc_hvT9GhO7TtEuO9xwUx0xrEm_naxJv4wf4x_lsOZ6mNtA8gQ_lRAEZApdHJrivAORMCK-MBQq0WEB_HLQXerkALlu9JDRpGytNvfewTZqWckgGAMzXoT4AD7GMZMDbkUVHzajlFVQo_b5YdBK76xLbtTIG5NF9yobPZ2dbkeetugPLrWNCnICBM1g60e40vWwJ7Oxa8dCMSxsOFEITE4jNZQU1agQejpeBxabTlrQMwjAOvD-eUkvi3ZdAwVePlu6AyQJ4CSfl4MBkiy94HfdKa2prlOE0ahuProzXuAxzdUA4uLyGXCDzlPurlf9q5T9AK19XKvkNfEt-mW9XTXdFNW8xHPnx7tHpfdmkgaG7h0f9HePfSOff_fosy3f49MdKXAJ4ZMJ5lfekLZkw-L2bcABw1YZR7PuQzn-VkDxMUJr6W92wSRs4ELrtBP-B-hg8cI2VE0yP2i6K27brMMK4Xv5WHMbL4l36Q-NvQwldEroELhtnU6VT5az_65z0Xfo2NkzTD2RfxSnFnx0T3J5Sn2-mWSYw_eC27lzTHbQL7zP9e9esLxSh-1HYoWyB7vPZ_7xqBZbMCZtyyS1ngn_zKRvLZqdc5_oNuEP5ctWcwpJ4l34Zl-S-497q_57_9q7I5ZZnAkMFYq818aMD7PtV4AJJWmp1GKc_Xlyk_25Wu0LcuLkuicafHddowiTpL7WzdTsxnlvpT1e50DuL6EHluEkvc3P89efEo3JC9--XpP-2d25LFCpX4PnXm5rdRe9NvJRtdWWm0-knVaHtbYr5PaPIfzCivyameC3ev_x4PY_0pICCs0oqY3luzjd_hleSlzxn0ooTHJRGqFE0frzhZRgXhvU1r2rBqzrkvMZhmhlNOn6w8SnSzNao_eAj4SdnLFgUwfbQPV67frDGDbCbu86L0Wr__vbuXVd5fn7kBoUCBkJZyNBaj9EDiJ-B2_O-Juyq4CtiA1zmGpnxWHwM0h0y1PAGDTPGG5Hl7Knsaf80StlTgY0_0F66cSpz1u_ChFHnzPgoMifzGlQJXGsUeGTSgrGuLCFUbz0pNnGxjtdsgpsoiaP5crZeJpN6s8rn0WI9Wy-W6zJbrbISV2U5m2U0o_NlEZcTvukaOJ5FlM6TabSk8TLOymi5nGGSZGQ-wwPjYirE8eC5MeHGONxE0WKdLCaCZShMeIBLqcQPCFcJpWTxMtEbv-gpc5Uh85ngxpqzG8utwM3bodHqOGJER_CPdrLksjLhUe_FXHs70g1FZxpHqsyxmDgtNldE57Z22TT38rz3eLr_nhqtfsLcq16IwktUF-ZxQ_8dAAD__6gbGVQ">