<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">