diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h index 0f994e297a87..f618b20603e6 100644 --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -507,7 +507,9 @@ private: _And< is_constructible<_Tp, _UfQual>, is_constructible<_Err, _OtherErrQual>, _If<_Not, bool>>::value, - _And< _Not&>>, + _And< + _Not<_And, is_same<_Err, _OtherErr>>>, // use the copy constructor instead, see #92676 + _Not&>>, _Not>>, _Not&>>, _Not>>, diff --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp index 581df51207da..ba9831750c84 100644 --- a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp +++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp @@ -62,6 +62,16 @@ static_assert(!std::is_trivially_copy_constructible_v>); static_assert(!std::is_trivially_copy_constructible_v>); +struct Any { + constexpr Any() = default; + constexpr Any(const Any&) = default; + constexpr Any& operator=(const Any&) = default; + + template + requires(!std::is_same_v> && std::is_copy_constructible_v>) + constexpr Any(T&&) {} +}; + constexpr bool test() { // copy the value non-trivial { @@ -109,6 +119,16 @@ constexpr bool test() { assert(!e2.has_value()); } + { + // TODO(LLVM 20): Remove once we drop support for Clang 17 +#if defined(TEST_CLANG_VER) && TEST_CLANG_VER >= 1800 + // https://github.com/llvm/llvm-project/issues/92676 + std::expected e1; + auto e2 = e1; + assert(e2.has_value()); +#endif + } + return true; }