https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121278
Bug ID: 121278 Summary: comparison of iterators does not compile for containers of std::expected or std::function that returns an std::expected Product: gcc Version: 15.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jacob.statnekov at gmail dot com Target Milestone: --- compiler : gcc 15.1.0 OS : linux 5.4.17-2136.343.5.1.el8uekx86_64 x86_64 GNU/Linux gcc was built with --enable-languages=c,c++ --prefix=XXX --with-gmp=XXX --with-mpc=XXX --with-mpfr=XXX --disable-mulitlib build invocation : -g -o output.s -masm=intel -fno-verbose-asm -S -fdiagnostics-color=always -std=c++23 example.cpp compilation error : In file included from <source>:2: /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/expected: In substitution of 'template<class _Up> requires !(__is_expected<_Up>) && requires(const _Tp& __t, const _Up& __u) {{__t == __u} -> decltype(auto) [requires std::convertible_to<<placeholder>, bool>];} constexpr bool std::operator==(const expected<int, __cxx11::basic_string<char> >&, const _Up&) [with _Up = __gnu_cxx::__normal_iterator<std::expected<int, std::__cxx11::basic_string<char> >*, std::vector<std::expected<int, std::__cxx11::basic_string<char> > > >]': /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/expected:1175:12: required by substitution of 'template<class _Up> requires !(__is_expected<_Up>) && requires(const _Tp& __t, const _Up& __u) {{__t == __u} -> decltype(auto) [requires std::convertible_to<<placeholder>, bool>];} constexpr bool std::operator==(const expected<int, __cxx11::basic_string<char> >&, const _Up&) [with _Up = __gnu_cxx::__normal_iterator<std::expected<int, std::__cxx11::basic_string<char> >*, std::vector<std::expected<int, std::__cxx11::basic_string<char> > > >]' 1175 | { __t == __u } -> convertible_to<bool>; | ~~~~^~~~~~ <source>:9:29: required from here 9 | bool isEmpty = begin == end; | ^~~ /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/expected:1178:2: required by the constraints of 'template<class _Tp, class _Er> template<class _Up> requires !(__is_expected<_Up>) && requires(const _Tp& __t, const _Up& __u) {{__t == __u} -> decltype(auto) [requires std::convertible_to<<placeholder>, bool>];} constexpr bool std::operator==(const expected<_Tp, _Er>&, const _Up&)' /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/expected:1174:7: in requirements with 'const _Tp& __t', 'const _Up& __u' [with _Tp = int; _Up = __gnu_cxx::__normal_iterator<std::expected<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, std::vector<std::expected<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::expected<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >] /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/expected:1174:14: error: satisfaction of atomic constraint 'requires(const _Tp& __t, const _Up& __u) {{__t == __u} -> decltype(auto) [requires std::convertible_to<<placeholder>, bool>];} [with _Tp = _Tp; _Up = _Up]' depends on itself 1174 | && requires (const _Tp& __t, const _Up& __u) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1175 | { __t == __u } -> convertible_to<bool>; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1176 | } | ~ Compiler returned: 1 offending code: #include <vector> #include <expected> #include <string> int main() { std::vector<std::expected<int, std::string>> v; decltype(v)::iterator begin(v.begin()), end(v.end()); bool isEmpty = begin == end; // error here } Note : This constraint error appears for container iterators and containers of std::functions that return an std::expected. I've tried most of the stl containers as well as a few boost containers and the constraint error is the same. Here is a side-by-side comparison of the above code with gcc 14.3 and gcc 15.1 https://godbolt.org/z/3boo43K1W