[libcxx-commits] [libcxx] 9fd3c41 - [libc++] Fix `unexpected` heterogeneous comparison (#115249)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Nov 7 08:49:34 PST 2024


Author: A. Jiang
Date: 2024-11-07T11:49:29-05:00
New Revision: 9fd3c4115cf2cd3da1405e1f2c38d53582b5dc81

URL: https://github.com/llvm/llvm-project/commit/9fd3c4115cf2cd3da1405e1f2c38d53582b5dc81
DIFF: https://github.com/llvm/llvm-project/commit/9fd3c4115cf2cd3da1405e1f2c38d53582b5dc81.diff

LOG: [libc++] Fix `unexpected` heterogeneous comparison (#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 #115326

Added: 
    

Modified: 
    libcxx/include/__expected/unexpected.h
    libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__expected/unexpected.h b/libcxx/include/__expected/unexpected.h
index c7fe3c52e43114..cf110bcf69a827 100644
--- a/libcxx/include/__expected/unexpected.h
+++ b/libcxx/include/__expected/unexpected.h
@@ -108,7 +108,7 @@ class unexpected {
 
   template <class _Err2>
   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) {
-    return __x.__unex_ == __y.__unex_;
+    return __x.__unex_ == __y.error();
   }
 
 private:

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
index 3c29cf97580460..4824151d0e44c4 100644
--- a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
@@ -20,18 +20,29 @@
 #include <expected>
 #include <utility>
 
-struct Error{
+struct Error {
   int i;
   friend constexpr bool operator==(const Error&, const Error&) = default;
+  friend constexpr bool operator==(const Error& lhs, int rhs) noexcept { return lhs.i == rhs; }
 };
 
 constexpr bool test() {
   std::unexpected<Error> unex1(Error{2});
   std::unexpected<Error> unex2(Error{3});
   std::unexpected<Error> unex3(Error{2});
+
   assert(unex1 == unex3);
   assert(unex1 != unex2);
   assert(unex2 != unex3);
+
+  std::unexpected<int> unex_i1(1);
+  std::unexpected<int> unex_i2(2);
+
+  assert(unex1 != unex_i1);
+  assert(unex_i1 != unex1);
+  assert(unex1 == unex_i2);
+  assert(unex_i2 == unex1);
+
   return true;
 }
 


        


More information about the libcxx-commits mailing list