Skip to content

Commit 9fd3c41

Browse files
[libc++] Fix unexpected heterogeneous comparison (llvm#115249)
Currently, libc++ incorrectly rejects heterogeneous comparison of `unexpected`, because the `operator==` is only a hidden friend of `unexpected<_Err>` but not of `unexpected<_Err2>`. We need to call the `error()` member function on `__y`. Fixes llvm#115326
1 parent ef353b0 commit 9fd3c41

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

libcxx/include/__expected/unexpected.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class unexpected {
108108

109109
template <class _Err2>
110110
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) {
111-
return __x.__unex_ == __y.__unex_;
111+
return __x.__unex_ == __y.error();
112112
}
113113

114114
private:

libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,29 @@
2020
#include <expected>
2121
#include <utility>
2222

23-
struct Error{
23+
struct Error {
2424
int i;
2525
friend constexpr bool operator==(const Error&, const Error&) = default;
26+
friend constexpr bool operator==(const Error& lhs, int rhs) noexcept { return lhs.i == rhs; }
2627
};
2728

2829
constexpr bool test() {
2930
std::unexpected<Error> unex1(Error{2});
3031
std::unexpected<Error> unex2(Error{3});
3132
std::unexpected<Error> unex3(Error{2});
33+
3234
assert(unex1 == unex3);
3335
assert(unex1 != unex2);
3436
assert(unex2 != unex3);
37+
38+
std::unexpected<int> unex_i1(1);
39+
std::unexpected<int> unex_i2(2);
40+
41+
assert(unex1 != unex_i1);
42+
assert(unex_i1 != unex1);
43+
assert(unex1 == unex_i2);
44+
assert(unex_i2 == unex1);
45+
3546
return true;
3647
}
3748

0 commit comments

Comments
 (0)