On Mon, 5 May 2025 at 19:50, Patrick Palka <[email protected]> wrote:
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk/15?
OK for trunk and 15.
>
> -- >8 --
>
> This std::expected friend operator== is prone to constraint recursion
> after CWG 2369 for the same reason as basic_const_iterator's comparison
> operators were before the r15-7757-g4342c50ca84ae5 workaround. This
> patch works around the constraint recursion here in a similar manner,
> by making the function parameter of type std::expected dependent in a
> trivial way.
>
> PR libstdc++/119714
> PR libstdc++/112490
>
> libstdc++-v3/ChangeLog:
>
> * include/std/expected (expected::operator==): Replace
> non-dependent std::expected function parameter with a dependent
> one of type expected<_Vp, _Er> where _Vp matches _Tp.
> * testsuite/20_util/expected/119714.cc: New test.
> ---
> libstdc++-v3/include/std/expected | 4 ++--
> libstdc++-v3/testsuite/20_util/expected/119714.cc | 9 +++++++++
> 2 files changed, 11 insertions(+), 2 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/20_util/expected/119714.cc
>
> diff --git a/libstdc++-v3/include/std/expected
> b/libstdc++-v3/include/std/expected
> index 5dc1dfbe5b8a..60f1565f15b9 100644
> --- a/libstdc++-v3/include/std/expected
> +++ b/libstdc++-v3/include/std/expected
> @@ -1169,13 +1169,13 @@ namespace __expected
> return !__y.has_value() && bool(__x.error() == __y.error());
> }
>
> - template<typename _Up>
> + template<typename _Up, same_as<_Tp> _Vp>
> requires (!__expected::__is_expected<_Up>)
> && requires (const _Tp& __t, const _Up& __u) {
> { __t == __u } -> convertible_to<bool>;
> }
> friend constexpr bool
> - operator==(const expected& __x, const _Up& __v)
> + operator==(const expected<_Vp, _Er>& __x, const _Up& __v)
> noexcept(noexcept(bool(*__x == __v)))
> { return __x.has_value() && bool(*__x == __v); }
>
> diff --git a/libstdc++-v3/testsuite/20_util/expected/119714.cc
> b/libstdc++-v3/testsuite/20_util/expected/119714.cc
> new file mode 100644
> index 000000000000..a8dc6e891e1d
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/expected/119714.cc
> @@ -0,0 +1,9 @@
> +// { dg-do compile { target c++23 } }
> +
> +// PR libstdc++/119714 - constraint recursion with std::expected::operator==
> +
> +#include <expected>
> +#include <vector>
> +
> +using I = std::vector<std::expected<int,int>>::iterator;
> +static_assert(std::totally_ordered<I>);
> --
> 2.49.0.503.g6c0bd1fc70
>