[libcxx-commits] [libcxx] e356f68 - [libc++] Implement `std::expected` P0323R12

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 14 07:44:56 PST 2022


Author: Hui Xie
Date: 2022-12-14T15:43:42Z
New Revision: e356f681f6c46ac35f933dc0cef3b25ceee8b210

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

LOG: [libc++] Implement `std::expected` P0323R12

Implement `std::expected` https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html

Added tests

Differential Revision: https://reviews.llvm.org/D124516

address comment

Added: 
    libcxx/include/__expected/bad_expected_access.h
    libcxx/include/__expected/expected.h
    libcxx/include/__expected/unexpect.h
    libcxx/include/__expected/unexpected.h
    libcxx/include/expected
    libcxx/test/libcxx/utilities/expected/expected.expected/assert.arrow.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.expected/assert.deref.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.expected/assert.error.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.expected/value_or.mandates.verify.cpp
    libcxx/test/libcxx/utilities/expected/expected.unexpected/class.mandates.verify.cpp
    libcxx/test/libcxx/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.unexpected/swap.mandates.verify.cpp
    libcxx/test/libcxx/utilities/expected/expected.void/assert.deref.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.void/assert.error.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp
    libcxx/test/libcxx/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp
    libcxx/test/libcxx/utilities/expected/types.h
    libcxx/test/libcxx/utilities/expected/version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
    libcxx/test/std/utilities/expected/expected.bad/ctor.error.pass.cpp
    libcxx/test/std/utilities/expected/expected.bad/error.member.pass.cpp
    libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/assign.U.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/assign.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/assign.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/emplace.intializer_list.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/assign/emplace.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.default.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace_init_list.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect_init_list.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/dtor.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/arrow.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/bool.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/deref.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/error.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/value.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/observers/value_or.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/swap/free.swap.pass.cpp
    libcxx/test/std/utilities/expected/expected.expected/swap/member.swap.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/ctad.compile.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.error.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace_init_list.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref_ref.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref_ref.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.free.pass.cpp
    libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.member.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/assign/assign.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/assign/assign.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/assign/emplace.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.default.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.inplace.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect_init_list.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.copy.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.move.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/dtor.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/observers/bool.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/observers/deref.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/observers/error.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/observers/has_value.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/observers/value.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/swap/free.swap.pass.cpp
    libcxx/test/std/utilities/expected/expected.void/swap/member.swap.pass.cpp
    libcxx/test/std/utilities/expected/types.h

Modified: 
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/docs/Status/Cxx2bIssues.csv
    libcxx/docs/Status/Cxx2bPapers.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/__type_traits/is_member_pointer.h
    libcxx/include/__type_traits/is_scalar.h
    libcxx/include/__type_traits/is_void.h
    libcxx/include/libcxx.imp
    libcxx/include/module.modulemap.in
    libcxx/include/version
    libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
    libcxx/test/libcxx/clang_tidy.sh.cpp
    libcxx/test/libcxx/double_include.sh.cpp
    libcxx/test/libcxx/min_max_macros.compile.pass.cpp
    libcxx/test/libcxx/modules_include.sh.cpp
    libcxx/test/libcxx/nasty_macros.compile.pass.cpp
    libcxx/test/libcxx/no_assert_include.compile.pass.cpp
    libcxx/test/libcxx/private_headers.verify.cpp
    libcxx/test/libcxx/transitive_includes.sh.cpp
    libcxx/test/libcxx/transitive_includes/cxx03.csv
    libcxx/test/libcxx/transitive_includes/cxx11.csv
    libcxx/test/libcxx/transitive_includes/cxx14.csv
    libcxx/test/libcxx/transitive_includes/cxx17.csv
    libcxx/test/libcxx/transitive_includes/cxx20.csv
    libcxx/test/libcxx/transitive_includes/cxx2b.csv
    libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
    libcxx/utils/generate_feature_test_macro_components.py
    libcxx/utils/generate_header_inclusion_tests.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index a1371267cd32b..c4ecbd6279924 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -318,6 +318,8 @@ Status
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_typeinfo``                  *unimplemented*
     ------------------------------------------------- -----------------
+    ``__cpp_lib_expected``                            ``202202L``
+    ------------------------------------------------- -----------------
     ``__cpp_lib_forward_like``                        ``202207L``
     ------------------------------------------------- -----------------
     ``__cpp_lib_invoke_r``                            *unimplemented*

diff  --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index 4f3d82b530397..67f46373029e0 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -167,11 +167,11 @@
 "`3671 <https://wg21.link/LWG3671>`__","``atomic_fetch_xor`` missing from ``stdatomic.h``","July 2022","",""
 "`3672 <https://wg21.link/LWG3672>`__","``common_iterator::operator->()`` should return by value","July 2022","","","|ranges|"
 "`3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","",""
-"`3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","July 2022","",""
+"`3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","July 2022","Complete","16.0"
 "`3692 <https://wg21.link/LWG3692>`__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","July 2022","","","|ranges| |spaceship|"
 "`3701 <https://wg21.link/LWG3701>`__","Make ``formatter<remove_cvref_t<const charT[N]>, charT>`` requirement explicit","July 2022","","","|format|"
 "`3702 <https://wg21.link/LWG3702>`__","Should ``zip_transform_view::iterator`` remove ``operator<``","July 2022","","","|ranges| |spaceship|"
-"`3703 <https://wg21.link/LWG3703>`__","Missing requirements for ``expected<T, E>`` requires ``is_void<T>``","July 2022","",""
+"`3703 <https://wg21.link/LWG3703>`__","Missing requirements for ``expected<T, E>`` requires ``is_void<T>``","July 2022","Complete","16.0"
 "`3704 <https://wg21.link/LWG3704>`__","LWG 2059 added overloads that might be ill-formed for sets","July 2022","",""
 "`3705 <https://wg21.link/LWG3705>`__","Hashability shouldn't depend on basic_string's allocator","July 2022","|Complete|","16.0"
 "`3707 <https://wg21.link/LWG3707>`__","chunk_view::outer-iterator::value_type::size should return unsigned type","July 2022","","","|ranges|"

diff  --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index 402e233aaea24..e6245261a7d0a 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -38,7 +38,7 @@
 "`P2393R1 <https://wg21.link/P2393R1>`__","LWG","Cleaning up ``integer``-class types","October 2021","",""
 "`P2401R0 <https://wg21.link/P2401R0>`__","LWG","Add a conditional ``noexcept`` specification to ``std::exchange``","October 2021","|Complete|","14.0"
 "","","","","",""
-"`P0323R12 <https://wg21.link/P0323R12>`__","LWG","``std::expected``","February 2022","",""
+"`P0323R12 <https://wg21.link/P0323R12>`__","LWG","``std::expected``","February 2022","|Complete|","16.0"
 "`P0533R9 <https://wg21.link/P0533R9>`__","LWG","``constexpr`` for ``<cmath>`` and ``<cstdlib>``","February 2022","",""
 "`P0627R6 <https://wg21.link/P0627R6>`__","LWG","Function to mark unreachable code","February 2022","|Complete|","15.0"
 "`P1206R7 <https://wg21.link/P1206R7>`__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","","|ranges|"
@@ -86,7 +86,7 @@
 "`P2517R1 <https://wg21.link/P2517R1>`__","LWG","Add a conditional ``noexcept`` specification to ``std::apply``","July 2022","",""
 "`P2520R0 <https://wg21.link/P2520R0>`__","LWG","``move_iterator`` should be a random access iterator","July 2022","","","|ranges|"
 "`P2540R1 <https://wg21.link/P2540R1>`__","LWG","Empty Product for certain Views","July 2022","","","|ranges|"
-"`P2549R1 <https://wg21.link/P2549R1>`__","LWG","``std::unexpected`` should have ``error()`` as member accessor","July 2022","",""
+"`P2549R1 <https://wg21.link/P2549R1>`__","LWG","``std::unexpected`` should have ``error()`` as member accessor","July 2022","|Complete|","16.0"
 "`P2553R1 <https://wg21.link/P2553R1>`__","LWG","Make ``mdspan`` ``size_type`` controllable","July 2022","",""
 "`P2554R0 <https://wg21.link/P2554R0>`__","LWG","C-Array Interoperability of MDSpan","July 2022","",""
 "`P2585R0 <https://wg21.link/P2585R0>`__","LWG","Improving default container formatting","July 2022","",""

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 7dc3ffa252a8a..1c8ce896ada50 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -269,6 +269,10 @@ set(files
   __debug
   __debug_utils/randomize_range.h
   __errc
+  __expected/bad_expected_access.h
+  __expected/expected.h
+  __expected/unexpect.h
+  __expected/unexpected.h
   __filesystem/copy_options.h
   __filesystem/directory_entry.h
   __filesystem/directory_iterator.h
@@ -740,6 +744,7 @@ set(files
   errno.h
   exception
   execution
+  expected
   experimental/__config
   experimental/__memory
   experimental/algorithm

diff  --git a/libcxx/include/__expected/bad_expected_access.h b/libcxx/include/__expected/bad_expected_access.h
new file mode 100644
index 0000000000000..361eab4b60187
--- /dev/null
+++ b/libcxx/include/__expected/bad_expected_access.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
+#define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
+
+#include <__config>
+#include <__utility/move.h>
+
+#include <exception>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Err>
+class bad_expected_access;
+
+template <>
+class bad_expected_access<void> : public exception {
+protected:
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept                             = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&)            = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&)                 = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&)      = default;
+  ~bad_expected_access() override                                                  = default;
+
+public:
+  // The way this has been designed (by using a class template below) means that we'll already
+  // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch
+  // of work to do. So it is not worth hiding the <void> specialization in the dylib, given that
+  // it adds deployment target restrictions.
+  const char* what() const noexcept override { return "bad access to std::expected"; }
+};
+
+template <class _Err>
+class bad_expected_access : public bad_expected_access<void> {
+public:
+  _LIBCPP_HIDE_FROM_ABI explicit bad_expected_access(_Err __e) : __unex_(std::move(__e)) {}
+
+  _LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; }
+  _LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; }
+  _LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); }
+  _LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); }
+
+private:
+  _Err __unex_;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H

diff  --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
new file mode 100644
index 0000000000000..593ec4bb39f88
--- /dev/null
+++ b/libcxx/include/__expected/expected.h
@@ -0,0 +1,971 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___EXPECTED_EXPECTED_H
+#define _LIBCPP___EXPECTED_EXPECTED_H
+
+#include <__assert>
+#include <__config>
+#include <__expected/bad_expected_access.h>
+#include <__expected/unexpect.h>
+#include <__expected/unexpected.h>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_move_assignable.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_assignable.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/is_trivially_move_constructible.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/lazy.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <__utility/transaction.h>
+#include <cstdlib> // for std::abort
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __expected {
+
+template <class _Err, class _Arg>
+_LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
+#  ifndef _LIBCPP_NO_EXCEPTIONS
+  throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
+#  else
+  (void)__arg;
+  std::abort();
+#  endif
+}
+
+} // namespace __expected
+
+template <class _Tp, class _Err>
+class expected {
+  static_assert(
+      !is_reference_v<_Tp> &&
+          !is_function_v<_Tp> &&
+          !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
+          !is_same_v<remove_cv_t<_Tp>, unexpect_t> &&
+          !__unexpected::__is_unexpected<remove_cv_t<_Tp>>::value &&
+          __unexpected::__valid_unexpected<_Err>::value
+      ,
+      "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
+      "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
+      "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
+      "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
+      "template argument for unexpected is ill-formed.");
+
+  template <class _Up, class _OtherErr>
+  friend class expected;
+
+public:
+  using value_type      = _Tp;
+  using error_type      = _Err;
+  using unexpected_type = unexpected<_Err>;
+
+  template <class _Up>
+  using rebind = expected<_Up, error_type>;
+
+  // [expected.object.ctor], constructors
+  _LIBCPP_HIDE_FROM_ABI constexpr expected()
+    noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
+    requires is_default_constructible_v<_Tp>
+      : __has_val_(true) {
+    std::construct_at(std::addressof(__union_.__val_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
+    requires(is_copy_constructible_v<_Tp> &&
+             is_copy_constructible_v<_Err> &&
+             is_trivially_copy_constructible_v<_Tp> &&
+             is_trivially_copy_constructible_v<_Err>)
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other)
+    noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
+    requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
+             !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
+      : __has_val_(__other.__has_val_) {
+    if (__has_val_) {
+      std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
+    } else {
+      std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
+    }
+  }
+
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
+    requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err>
+              && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other)
+    noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
+    requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
+             !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
+      : __has_val_(__other.__has_val_) {
+    if (__has_val_) {
+      std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_));
+    } else {
+      std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_));
+    }
+  }
+
+private:
+  template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual>
+  using __can_convert =
+      _And< is_constructible<_Tp, _UfQual>,
+            is_constructible<_Err, _OtherErrQual>,
+            _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>,
+            _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>,
+            _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>,
+            _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>,
+            _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>,
+            _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>,
+            _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>,
+            _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>,
+            _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
+            _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
+            _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
+            _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
+
+
+public:
+  template <class _Up, class _OtherErr>
+    requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> ||
+                                           !is_convertible_v<const _OtherErr&, _Err>)
+  expected(const expected<_Up, _OtherErr>& __other)
+    noexcept(is_nothrow_constructible_v<_Tp, const _Up&> &&
+             is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
+      : __has_val_(__other.__has_val_) {
+    if (__has_val_) {
+      std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
+    } else {
+      std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
+    }
+  }
+
+  template <class _Up, class _OtherErr>
+    requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
+  expected(expected<_Up, _OtherErr>&& __other)
+    noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
+      : __has_val_(__other.__has_val_) {
+    if (__has_val_) {
+      std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_));
+    } else {
+      std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_));
+    }
+  }
+
+  template <class _Up = _Tp>
+    requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
+             !__unexpected::__is_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
+  expected(_Up&& __u)
+    noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
+      : __has_val_(true) {
+    std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u));
+  }
+
+
+  template <class _OtherErr>
+    requires is_constructible_v<_Err, const _OtherErr&>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
+  expected(const unexpected<_OtherErr>& __unex)
+    noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), __unex.error());
+  }
+
+  template <class _OtherErr>
+    requires is_constructible_v<_Err, _OtherErr>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
+  expected(unexpected<_OtherErr>&& __unex)
+    noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error()));
+  }
+
+  template <class... _Args>
+    requires is_constructible_v<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args)
+    noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
+      : __has_val_(true) {
+    std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
+  }
+
+  template <class _Up, class... _Args>
+    requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit
+  expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
+    noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
+      : __has_val_(true) {
+    std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
+  }
+
+  template <class... _Args>
+    requires is_constructible_v<_Err, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
+    noexcept(is_nothrow_constructible_v<_Err, _Args...>)  // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...);
+  }
+
+  template <class _Up, class... _Args>
+    requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit
+  expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
+    noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
+  }
+
+  // [expected.object.dtor], destructor
+
+  _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
+    requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
+    requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
+  {
+    if (__has_val_) {
+      std::destroy_at(std::addressof(__union_.__val_));
+    } else {
+      std::destroy_at(std::addressof(__union_.__unex_));
+    }
+  }
+
+private:
+  template <class _T1, class _T2, class... _Args>
+  _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) {
+    if constexpr (is_nothrow_constructible_v<_T1, _Args...>) {
+      std::destroy_at(std::addressof(__oldval));
+      std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
+    } else if constexpr (is_nothrow_move_constructible_v<_T1>) {
+      _T1 __tmp(std::forward<_Args>(__args)...);
+      std::destroy_at(std::addressof(__oldval));
+      std::construct_at(std::addressof(__newval), std::move(__tmp));
+    } else {
+      static_assert(
+          is_nothrow_move_constructible_v<_T2>,
+          "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
+          "be reverted to the previous state in case an exception is thrown during the assignment.");
+      _T2 __tmp(std::move(__oldval));
+      std::destroy_at(std::addressof(__oldval));
+      __transaction __trans([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); });
+      std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
+      __trans.__complete();
+    }
+  }
+
+public:
+  // [expected.object.assign], assignment
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
+    noexcept(is_nothrow_copy_assignable_v<_Tp> &&
+             is_nothrow_copy_constructible_v<_Tp> &&
+             is_nothrow_copy_assignable_v<_Err> &&
+             is_nothrow_copy_constructible_v<_Err>) // strengthened
+    requires(is_copy_assignable_v<_Tp> &&
+             is_copy_constructible_v<_Tp> &&
+             is_copy_assignable_v<_Err> &&
+             is_copy_constructible_v<_Err> &&
+             (is_nothrow_move_constructible_v<_Tp> ||
+              is_nothrow_move_constructible_v<_Err>))
+  {
+    if (__has_val_ && __rhs.__has_val_) {
+      __union_.__val_ = __rhs.__union_.__val_;
+    } else if (__has_val_) {
+      __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_);
+    } else if (__rhs.__has_val_) {
+      __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_);
+    } else {
+      __union_.__unex_ = __rhs.__union_.__unex_;
+    }
+    // note: only reached if no exception+rollback was done inside __reinit_expected
+    __has_val_ = __rhs.__has_val_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
+    noexcept(is_nothrow_move_assignable_v<_Tp> &&
+             is_nothrow_move_constructible_v<_Tp> &&
+             is_nothrow_move_assignable_v<_Err> &&
+             is_nothrow_move_constructible_v<_Err>)
+    requires(is_move_constructible_v<_Tp> &&
+             is_move_assignable_v<_Tp> &&
+             is_move_constructible_v<_Err> &&
+             is_move_assignable_v<_Err> &&
+             (is_nothrow_move_constructible_v<_Tp> ||
+              is_nothrow_move_constructible_v<_Err>))
+  {
+    if (__has_val_ && __rhs.__has_val_) {
+      __union_.__val_ = std::move(__rhs.__union_.__val_);
+    } else if (__has_val_) {
+      __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_));
+    } else if (__rhs.__has_val_) {
+      __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_));
+    } else {
+      __union_.__unex_ = std::move(__rhs.__union_.__unex_);
+    }
+    // note: only reached if no exception+rollback was done inside __reinit_expected
+    __has_val_ = __rhs.__has_val_;
+    return *this;
+  }
+
+  template <class _Up = _Tp>
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
+    requires(!is_same_v<expected, remove_cvref_t<_Up>> &&
+             !__unexpected::__is_unexpected<remove_cvref_t<_Up>>::value &&
+             is_constructible_v<_Tp, _Up> &&
+             is_assignable_v<_Tp&, _Up> &&
+             (is_nothrow_constructible_v<_Tp, _Up> ||
+              is_nothrow_move_constructible_v<_Tp> ||
+              is_nothrow_move_constructible_v<_Err>))
+  {
+    if (__has_val_) {
+      __union_.__val_ = std::forward<_Up>(__v);
+    } else {
+      __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v));
+      __has_val_ = true;
+    }
+    return *this;
+  }
+
+private:
+  template <class _OtherErrQual>
+  static constexpr bool __can_assign_from_unexpected =
+      _And< is_constructible<_Err, _OtherErrQual>,
+            is_assignable<_Err&, _OtherErrQual>,
+            _Lazy<_Or,
+                  is_nothrow_constructible<_Err, _OtherErrQual>,
+                  is_nothrow_move_constructible<_Tp>,
+                  is_nothrow_move_constructible<_Err>> >::value;
+
+public:
+  template <class _OtherErr>
+    requires(__can_assign_from_unexpected<const _OtherErr&>)
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
+    if (__has_val_) {
+      __reinit_expected(__union_.__unex_, __union_.__val_, __un.error());
+      __has_val_ = false;
+    } else {
+      __union_.__unex_ = __un.error();
+    }
+    return *this;
+  }
+
+  template <class _OtherErr>
+    requires(__can_assign_from_unexpected<_OtherErr>)
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
+    if (__has_val_) {
+      __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error()));
+      __has_val_ = false;
+    } else {
+      __union_.__unex_ = std::move(__un.error());
+    }
+    return *this;
+  }
+
+  template <class... _Args>
+    requires is_nothrow_constructible_v<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
+    if (__has_val_) {
+      std::destroy_at(std::addressof(__union_.__val_));
+    } else {
+      std::destroy_at(std::addressof(__union_.__unex_));
+      __has_val_ = true;
+    }
+    return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
+  }
+
+  template <class _Up, class... _Args>
+    requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept {
+    if (__has_val_) {
+      std::destroy_at(std::addressof(__union_.__val_));
+    } else {
+      std::destroy_at(std::addressof(__union_.__unex_));
+      __has_val_ = true;
+    }
+    return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
+  }
+
+
+public:
+  // [expected.object.swap], swap
+  _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
+    noexcept(is_nothrow_move_constructible_v<_Tp> &&
+             is_nothrow_swappable_v<_Tp> &&
+             is_nothrow_move_constructible_v<_Err> &&
+             is_nothrow_swappable_v<_Err>)
+    requires(is_swappable_v<_Tp> &&
+             is_swappable_v<_Err> &&
+             is_move_constructible_v<_Tp> &&
+             is_move_constructible_v<_Err> &&
+             (is_nothrow_move_constructible_v<_Tp> ||
+              is_nothrow_move_constructible_v<_Err>))
+  {
+    auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
+      if constexpr (is_nothrow_move_constructible_v<_Err>) {
+        _Err __tmp(std::move(__with_err.__union_.__unex_));
+        std::destroy_at(std::addressof(__with_err.__union_.__unex_));
+        __transaction __trans([&] {
+          std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp));
+        });
+        std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_));
+        __trans.__complete();
+        std::destroy_at(std::addressof(__with_val.__union_.__val_));
+        std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp));
+      } else {
+        static_assert(is_nothrow_move_constructible_v<_Tp>,
+                      "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
+                      "that it can be reverted to the previous state in case an exception is thrown during swap.");
+        _Tp __tmp(std::move(__with_val.__union_.__val_));
+        std::destroy_at(std::addressof(__with_val.__union_.__val_));
+        __transaction __trans([&] { std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp)); });
+        std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
+        __trans.__complete();
+        std::destroy_at(std::addressof(__with_err.__union_.__unex_));
+        std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp));
+      }
+      __with_val.__has_val_ = false;
+      __with_err.__has_val_ = true;
+    };
+
+    if (__has_val_) {
+      if (__rhs.__has_val_) {
+        using std::swap;
+        swap(__union_.__val_, __rhs.__union_.__val_);
+      } else {
+        __swap_val_unex_impl(*this, __rhs);
+      }
+    } else {
+      if (__rhs.__has_val_) {
+        __swap_val_unex_impl(__rhs, *this);
+      } else {
+        using std::swap;
+        swap(__union_.__unex_, __rhs.__union_.__unex_);
+      }
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
+    noexcept(noexcept(__x.swap(__y)))
+    requires requires { __x.swap(__y); }
+  {
+    __x.swap(__y);
+  }
+
+  // [expected.object.obs], observers
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
+    return std::addressof(__union_.__val_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
+    return std::addressof(__union_.__val_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    return __union_.__val_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    return __union_.__val_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    return std::move(__union_.__val_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+    return std::move(__union_.__val_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
+    if (!__has_val_) {
+      __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
+    }
+    return __union_.__val_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
+    if (!__has_val_) {
+      __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
+    }
+    return __union_.__val_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
+    if (!__has_val_) {
+      __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
+    }
+    return std::move(__union_.__val_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
+    if (!__has_val_) {
+      __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
+    }
+    return std::move(__union_.__val_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return __union_.__unex_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return __union_.__unex_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return std::move(__union_.__unex_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return std::move(__union_.__unex_);
+  }
+
+  template <class _Up>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
+    static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
+    static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
+    return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v));
+  }
+
+  template <class _Up>
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
+    static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
+    static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
+    return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v));
+  }
+
+  // [expected.object.eq], equality operators
+  template <class _T2, class _E2>
+    requires(!is_void_v<_T2>)
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
+    if (__x.__has_val_ != __y.__has_val_) {
+      return false;
+    } else {
+      if (__x.__has_val_) {
+        return __x.__union_.__val_ == __y.__union_.__val_;
+      } else {
+        return __x.__union_.__unex_ == __y.__union_.__unex_;
+      }
+    }
+  }
+
+  template <class _T2>
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
+    return __x.__has_val_ && static_cast<bool>(__x.__union_.__val_ == __v);
+  }
+
+  template <class _E2>
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
+    return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __e.error());
+  }
+
+private:
+  struct __empty_t {};
+  // use named union because [[no_unique_address]] cannot be applied to an unnamed union
+  _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
+    _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
+
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
+      requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
+    = default;
+
+    // the expected's destructor handles this
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
+      requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
+    {}
+
+    _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
+    _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
+    _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
+  } __union_;
+
+  bool __has_val_;
+};
+
+template <class _Tp, class _Err>
+  requires is_void_v<_Tp>
+class expected<_Tp, _Err> {
+  static_assert(__unexpected::__valid_unexpected<_Err>::value,
+                "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
+                "valid argument for unexpected<E> is ill-formed");
+
+  template <class, class>
+  friend class expected;
+
+  template <class _Up, class _OtherErr, class _OtherErrQual>
+  using __can_convert =
+      _And< is_void<_Up>,
+            is_constructible<_Err, _OtherErrQual>,
+            _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
+            _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
+            _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
+            _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>;
+
+public:
+  using value_type      = _Tp;
+  using error_type      = _Err;
+  using unexpected_type = unexpected<_Err>;
+
+  template <class _Up>
+  using rebind = expected<_Up, error_type>;
+
+  // [expected.void.ctor], constructors
+  _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
+    requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs)
+    noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened
+    requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
+      : __has_val_(__rhs.__has_val_) {
+    if (!__rhs.__has_val_) {
+      std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
+    requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs)
+    noexcept(is_nothrow_move_constructible_v<_Err>)
+    requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
+      : __has_val_(__rhs.__has_val_) {
+    if (!__rhs.__has_val_) {
+      std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
+    }
+  }
+
+  template <class _Up, class _OtherErr>
+    requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
+  expected(const expected<_Up, _OtherErr>& __rhs)
+    noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
+      : __has_val_(__rhs.__has_val_) {
+    if (!__rhs.__has_val_) {
+      std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
+    }
+  }
+
+  template <class _Up, class _OtherErr>
+    requires __can_convert<_Up, _OtherErr, _OtherErr>::value
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
+  expected(expected<_Up, _OtherErr>&& __rhs)
+    noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
+      : __has_val_(__rhs.__has_val_) {
+    if (!__rhs.__has_val_) {
+      std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
+    }
+  }
+
+  template <class _OtherErr>
+    requires is_constructible_v<_Err, const _OtherErr&>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
+  expected(const unexpected<_OtherErr>& __unex)
+    noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), __unex.error());
+  }
+
+  template <class _OtherErr>
+    requires is_constructible_v<_Err, _OtherErr>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
+  expected(unexpected<_OtherErr>&& __unex)
+    noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error()));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {}
+
+  template <class... _Args>
+    requires is_constructible_v<_Err, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
+    noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...);
+  }
+
+  template <class _Up, class... _Args>
+    requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
+    noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
+      : __has_val_(false) {
+    std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
+  }
+
+  // [expected.void.dtor], destructor
+
+  _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
+    requires is_trivially_destructible_v<_Err>
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
+    requires(!is_trivially_destructible_v<_Err>)
+  {
+    if (!__has_val_) {
+      std::destroy_at(std::addressof(__union_.__unex_));
+    }
+  }
+
+  // [expected.void.assign], assignment
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
+    noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened
+    requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>)
+  {
+    if (__has_val_) {
+      if (!__rhs.__has_val_) {
+        std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
+        __has_val_ = false;
+      }
+    } else {
+      if (__rhs.__has_val_) {
+        std::destroy_at(std::addressof(__union_.__unex_));
+        __has_val_ = true;
+      } else {
+        __union_.__unex_ = __rhs.__union_.__unex_;
+      }
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
+    noexcept(is_nothrow_move_assignable_v<_Err> &&
+             is_nothrow_move_constructible_v<_Err>)
+    requires(is_move_assignable_v<_Err> &&
+             is_move_constructible_v<_Err>)
+  {
+    if (__has_val_) {
+      if (!__rhs.__has_val_) {
+        std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
+        __has_val_ = false;
+      }
+    } else {
+      if (__rhs.__has_val_) {
+        std::destroy_at(std::addressof(__union_.__unex_));
+        __has_val_ = true;
+      } else {
+        __union_.__unex_ = std::move(__rhs.__union_.__unex_);
+      }
+    }
+    return *this;
+  }
+
+  template <class _OtherErr>
+    requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>)
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
+    if (__has_val_) {
+      std::construct_at(std::addressof(__union_.__unex_), __un.error());
+      __has_val_ = false;
+    } else {
+      __union_.__unex_ = __un.error();
+    }
+    return *this;
+  }
+
+  template <class _OtherErr>
+    requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>)
+  _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
+    if (__has_val_) {
+      std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error()));
+      __has_val_ = false;
+    } else {
+      __union_.__unex_ = std::move(__un.error());
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
+    if (!__has_val_) {
+      std::destroy_at(std::addressof(__union_.__unex_));
+      __has_val_ = true;
+    }
+  }
+
+  // [expected.void.swap], swap
+  _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
+    noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
+    requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>)
+  {
+    auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
+      std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
+      std::destroy_at(std::addressof(__with_err.__union_.__unex_));
+      __with_val.__has_val_ = false;
+      __with_err.__has_val_ = true;
+    };
+
+    if (__has_val_) {
+      if (!__rhs.__has_val_) {
+        __swap_val_unex_impl(*this, __rhs);
+      }
+    } else {
+      if (__rhs.__has_val_) {
+        __swap_val_unex_impl(__rhs, *this);
+      } else {
+        using std::swap;
+        swap(__union_.__unex_, __rhs.__union_.__unex_);
+      }
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
+    noexcept(noexcept(__x.swap(__y)))
+    requires requires { __x.swap(__y); }
+  {
+    __x.swap(__y);
+  }
+
+  // [expected.void.obs], observers
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
+    _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
+    if (!__has_val_) {
+      __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
+    if (!__has_val_) {
+      __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return __union_.__unex_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return __union_.__unex_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return std::move(__union_.__unex_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
+    _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
+    return std::move(__union_.__unex_);
+  }
+
+  // [expected.void.eq], equality operators
+  template <class _T2, class _E2>
+    requires is_void_v<_T2>
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
+    if (__x.__has_val_ != __y.__has_val_) {
+      return false;
+    } else {
+      return __x.__has_val_ || static_cast<bool>(__x.__union_.__unex_ == __y.__union_.__unex_);
+    }
+  }
+
+  template <class _E2>
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
+    return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __y.error());
+  }
+
+private:
+  struct __empty_t {};
+  // use named union because [[no_unique_address]] cannot be applied to an unnamed union
+  _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
+    _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
+
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
+      requires(is_trivially_destructible_v<_Err>)
+    = default;
+
+    // the expected's destructor handles this
+    _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
+      requires(!is_trivially_destructible_v<_Err>)
+    {}
+
+    _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
+    _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
+  } __union_;
+
+  bool __has_val_;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___EXPECTED_EXPECTED_H

diff  --git a/libcxx/include/__expected/unexpect.h b/libcxx/include/__expected/unexpect.h
new file mode 100644
index 0000000000000..20bafc1107c0d
--- /dev/null
+++ b/libcxx/include/__expected/unexpect.h
@@ -0,0 +1,32 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___EXPECTED_UNEXPECT_H
+#define _LIBCPP___EXPECTED_UNEXPECT_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct unexpect_t {
+  _LIBCPP_HIDE_FROM_ABI explicit unexpect_t() = default;
+};
+
+inline constexpr unexpect_t unexpect{};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___EXPECTED_UNEXPECT_H

diff  --git a/libcxx/include/__expected/unexpected.h b/libcxx/include/__expected/unexpected.h
new file mode 100644
index 0000000000000..22c307da82369
--- /dev/null
+++ b/libcxx/include/__expected/unexpected.h
@@ -0,0 +1,126 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___EXPECTED_UNEXPECTED_H
+#define _LIBCPP___EXPECTED_UNEXPECTED_H
+
+#include <__config>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/is_volatile.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Err>
+class unexpected;
+
+namespace __unexpected {
+
+template <class _Tp>
+struct __is_unexpected : false_type {};
+
+template <class _Err>
+struct __is_unexpected<unexpected<_Err>> : true_type {};
+
+template <class _Tp>
+using __valid_unexpected = _BoolConstant< //
+    is_object_v<_Tp> &&                   //
+    !is_array_v<_Tp> &&                   //
+    !__is_unexpected<_Tp>::value &&       //
+    !is_const_v<_Tp> &&                   //
+    !is_volatile_v<_Tp>                   //
+    >;
+
+} // namespace __unexpected
+
+template <class _Err>
+class unexpected {
+  static_assert(__unexpected::__valid_unexpected<_Err>::value,
+                "[expected.un.general] states a program that instantiates std::unexpected for a non-object type, an "
+                "array type, a specialization of unexpected, or a cv-qualified type is ill-formed.");
+
+public:
+  _LIBCPP_HIDE_FROM_ABI constexpr unexpected(const unexpected&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr unexpected(unexpected&&)      = default;
+
+  template <class _Error = _Err>
+    requires(!is_same_v<remove_cvref_t<_Error>, unexpected> && //
+             !is_same_v<remove_cvref_t<_Error>, in_place_t> && //
+             is_constructible_v<_Err, _Error>)
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(_Error&& __error) //
+      noexcept(is_nothrow_constructible_v<_Err, _Error>)                // strengthened
+      : __unex_(std::forward<_Error>(__error)) {}
+
+  template <class... _Args>
+    requires is_constructible_v<_Err, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, _Args&&... __args) //
+      noexcept(is_nothrow_constructible_v<_Err, _Args...>)                           // strengthened
+      : __unex_(std::forward<_Args>(__args)...) {}
+
+  template <class _Up, class... _Args>
+    requires is_constructible_v<_Err, initializer_list<_Up>&, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) //
+      noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
+      : __unex_(__il, std::forward<_Args>(__args)...) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(const unexpected&) = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(unexpected&&)      = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) {
+    static_assert(is_swappable_v<_Err>, "unexpected::swap requires is_swappable_v<E> to be true");
+    using std::swap;
+    swap(__unex_, __other.__unex_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
+    requires is_swappable_v<_Err>
+  {
+    __x.swap(__y);
+  }
+
+  template <class _Err2>
+  _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) {
+    return __x.__unex_ == __y.__unex_;
+  }
+
+private:
+  _Err __unex_;
+};
+
+template <class _Err>
+unexpected(_Err) -> unexpected<_Err>;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___EXPECTED_UNEXPECTED_H

diff  --git a/libcxx/include/__type_traits/is_member_pointer.h b/libcxx/include/__type_traits/is_member_pointer.h
index 8b4aff8563e9e..904d845f3327c 100644
--- a/libcxx/include/__type_traits/is_member_pointer.h
+++ b/libcxx/include/__type_traits/is_member_pointer.h
@@ -11,6 +11,7 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
+#include <__type_traits/is_member_function_pointer.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header

diff  --git a/libcxx/include/__type_traits/is_scalar.h b/libcxx/include/__type_traits/is_scalar.h
index ee856dbbfec77..b4dc70b5d8357 100644
--- a/libcxx/include/__type_traits/is_scalar.h
+++ b/libcxx/include/__type_traits/is_scalar.h
@@ -14,6 +14,7 @@
 #include <__type_traits/is_arithmetic.h>
 #include <__type_traits/is_enum.h>
 #include <__type_traits/is_member_pointer.h>
+#include <__type_traits/is_null_pointer.h>
 #include <__type_traits/is_pointer.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/__type_traits/is_void.h b/libcxx/include/__type_traits/is_void.h
index 1c7ad83f939df..d8ffdbd824461 100644
--- a/libcxx/include/__type_traits/is_void.h
+++ b/libcxx/include/__type_traits/is_void.h
@@ -11,6 +11,8 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header

diff  --git a/libcxx/include/expected b/libcxx/include/expected
new file mode 100644
index 0000000000000..486d0a21d0873
--- /dev/null
+++ b/libcxx/include/expected
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPECTED
+#define _LIBCPP_EXPECTED
+
+/*
+  Header <expected> synopsis
+
+namespace std {
+  // [expected.unexpected], class template unexpected
+  template<class E> class unexpected;
+
+  // [expected.bad], class template bad_expected_access
+  template<class E> class bad_expected_access;
+
+  // [expected.bad.void], specialization for void
+  template<> class bad_expected_access<void>;
+
+  // in-place construction of unexpected values
+  struct unexpect_t {
+    explicit unexpect_t() = default;
+  };
+  inline constexpr unexpect_t unexpect{};
+
+  // [expected.expected], class template expected
+  template<class T, class E> class expected;
+
+  // [expected.void], partial specialization of expected for void types
+  template<class T, class E> requires is_void_v<T> class expected<T, E>;
+}
+
+*/
+
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__config>
+#include <__expected/bad_expected_access.h>
+#include <__expected/expected.h>
+#include <__expected/unexpect.h>
+#include <__expected/unexpected.h>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#endif // _LIBCPP_EXPECTED
+

diff  --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 07fc9985c7003..b2a018e30b2f9 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -24,6 +24,7 @@
   { include: [ "@<__concepts/.*>", "private", "<concepts>", "public" ] },
   { include: [ "@<__coroutine/.*>", "private", "<coroutine>", "public" ] },
   { include: [ "@<__debug_utils/.*>", "private", "<debug_utils>", "public" ] },
+  { include: [ "@<__expected/.*>", "private", "<expected>", "public" ] },
   { include: [ "@<__filesystem/.*>", "private", "<filesystem>", "public" ] },
   { include: [ "@<__format/.*>", "private", "<format>", "public" ] },
   { include: [ "@<__functional/.*>", "private", "<functional>", "public" ] },

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 4033d2fe412d4..e6481a823e9b3 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -785,6 +785,17 @@ module std [system] {
     header "execution"
     export *
   }
+  module expected {
+    header "expected"
+    export *
+
+    module __expected {
+      module bad_expected_access          { private header "__expected/bad_expected_access.h" }
+      module expected                     { private header "__expected/expected.h" }
+      module unexpect                     { private header "__expected/unexpect.h" }
+      module unexpected                   { private header "__expected/unexpected.h" }
+    }
+  }
   module filesystem {
     @requires_LIBCXX_ENABLE_FILESYSTEM@
     header "filesystem"

diff  --git a/libcxx/include/version b/libcxx/include/version
index 9443564b0466b..1d10392964445 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -82,6 +82,7 @@ __cpp_lib_erase_if                                      202002L <deque> <forward
 __cpp_lib_exchange_function                             201304L <utility>
 __cpp_lib_execution                                     201902L <execution>
                                                         201603L // C++17
+__cpp_lib_expected                                      202202L <expected>
 __cpp_lib_filesystem                                    201703L <filesystem>
 __cpp_lib_format                                        202106L <format>
 __cpp_lib_forward_like                                  202207L <utility>
@@ -390,6 +391,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_constexpr_memory
 # define __cpp_lib_constexpr_memory                     202202L
 // # define __cpp_lib_constexpr_typeinfo                   202106L
+# define __cpp_lib_expected                             202202L
 # define __cpp_lib_forward_like                         202207L
 // # define __cpp_lib_invoke_r                             202106L
 # define __cpp_lib_is_scoped_enum                       202011L

diff  --git a/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp b/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
index c3179c26e50db..690c792657c34 100644
--- a/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
+++ b/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
@@ -306,464 +306,470 @@ int main(int, char**) { return 0; }
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_47
-#if defined(TEST_47) && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-#   include <filesystem>
+// RUN: %{build} -DTEST_46
+#if defined(TEST_46)
+#   include <expected>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_49
-#if defined(TEST_49)
-#   include <format>
+// RUN: %{build} -DTEST_48
+#if defined(TEST_48) && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+#   include <filesystem>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_50
 #if defined(TEST_50)
-#   include <forward_list>
+#   include <format>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_51
-#if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
-#   include <fstream>
+#if defined(TEST_51)
+#   include <forward_list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_52
-#if defined(TEST_52)
-#   include <functional>
+#if defined(TEST_52) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
+#   include <fstream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_53
-#if defined(TEST_53) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <future>
+#if defined(TEST_53)
+#   include <functional>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_54
-#if defined(TEST_54)
-#   include <initializer_list>
+#if defined(TEST_54) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <future>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_56
-#if defined(TEST_56) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <iomanip>
+// RUN: %{build} -DTEST_55
+#if defined(TEST_55)
+#   include <initializer_list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_57
 #if defined(TEST_57) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <ios>
+#   include <iomanip>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_58
-#if defined(TEST_58)
-#   include <iosfwd>
+#if defined(TEST_58) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <ios>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_59
-#if defined(TEST_59) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <iostream>
+#if defined(TEST_59)
+#   include <iosfwd>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_60
 #if defined(TEST_60) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <istream>
+#   include <iostream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_61
-#if defined(TEST_61)
-#   include <iterator>
+#if defined(TEST_61) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <istream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_62
-#if defined(TEST_62) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <latch>
+#if defined(TEST_62)
+#   include <iterator>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_63
-#if defined(TEST_63)
-#   include <limits>
+#if defined(TEST_63) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <latch>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_65
-#if defined(TEST_65)
-#   include <list>
+// RUN: %{build} -DTEST_64
+#if defined(TEST_64)
+#   include <limits>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_66
-#if defined(TEST_66) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <locale>
+#if defined(TEST_66)
+#   include <list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_68
-#if defined(TEST_68)
-#   include <map>
+// RUN: %{build} -DTEST_67
+#if defined(TEST_67) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <locale>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_70
-#if defined(TEST_70)
-#   include <memory>
+// RUN: %{build} -DTEST_69
+#if defined(TEST_69)
+#   include <map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_71
 #if defined(TEST_71)
-#   include <memory_resource>
+#   include <memory>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_72
-#if defined(TEST_72) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <mutex>
+#if defined(TEST_72)
+#   include <memory_resource>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_73
-#if defined(TEST_73)
-#   include <new>
+#if defined(TEST_73) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <mutex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_74
 #if defined(TEST_74)
-#   include <numbers>
+#   include <new>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_75
 #if defined(TEST_75)
-#   include <numeric>
+#   include <numbers>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_76
 #if defined(TEST_76)
-#   include <optional>
+#   include <numeric>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_77
-#if defined(TEST_77) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <ostream>
+#if defined(TEST_77)
+#   include <optional>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_78
-#if defined(TEST_78)
-#   include <queue>
+#if defined(TEST_78) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <ostream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_79
 #if defined(TEST_79)
-#   include <random>
+#   include <queue>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_80
 #if defined(TEST_80)
-#   include <ranges>
+#   include <random>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_81
 #if defined(TEST_81)
-#   include <ratio>
+#   include <ranges>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_82
-#if defined(TEST_82) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <regex>
+#if defined(TEST_82)
+#   include <ratio>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_83
-#if defined(TEST_83)
-#   include <scoped_allocator>
+#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <regex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_84
-#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <semaphore>
+#if defined(TEST_84)
+#   include <scoped_allocator>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_85
-#if defined(TEST_85)
+#if defined(TEST_85) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <semaphore>
+    using HandlerType = decltype(std::__libcpp_verbose_abort);
+#endif
+
+// RUN: %{build} -DTEST_86
+#if defined(TEST_86)
 #   include <set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_87
-#if defined(TEST_87) && !defined(_LIBCPP_HAS_NO_THREADS)
+// RUN: %{build} -DTEST_88
+#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <shared_mutex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_88
-#if defined(TEST_88)
+// RUN: %{build} -DTEST_89
+#if defined(TEST_89)
 #   include <span>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_89
-#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+// RUN: %{build} -DTEST_90
+#if defined(TEST_90) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 #   include <sstream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_90
-#if defined(TEST_90)
+// RUN: %{build} -DTEST_91
+#if defined(TEST_91)
 #   include <stack>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_94
-#if defined(TEST_94)
+// RUN: %{build} -DTEST_95
+#if defined(TEST_95)
 #   include <stdexcept>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_98
-#if defined(TEST_98) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+// RUN: %{build} -DTEST_99
+#if defined(TEST_99) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 #   include <streambuf>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_99
-#if defined(TEST_99)
+// RUN: %{build} -DTEST_100
+#if defined(TEST_100)
 #   include <string>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_101
-#if defined(TEST_101)
+// RUN: %{build} -DTEST_102
+#if defined(TEST_102)
 #   include <string_view>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_102
-#if defined(TEST_102) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+// RUN: %{build} -DTEST_103
+#if defined(TEST_103) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 #   include <strstream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_103
-#if defined(TEST_103)
+// RUN: %{build} -DTEST_104
+#if defined(TEST_104)
 #   include <system_error>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_105
-#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <thread>
-    using HandlerType = decltype(std::__libcpp_verbose_abort);
-#endif
-
 // RUN: %{build} -DTEST_106
-#if defined(TEST_106)
-#   include <tuple>
+#if defined(TEST_106) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <thread>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_107
 #if defined(TEST_107)
-#   include <type_traits>
+#   include <tuple>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_108
 #if defined(TEST_108)
-#   include <typeindex>
+#   include <type_traits>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_109
 #if defined(TEST_109)
-#   include <typeinfo>
+#   include <typeindex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_111
-#if defined(TEST_111)
-#   include <unordered_map>
+// RUN: %{build} -DTEST_110
+#if defined(TEST_110)
+#   include <typeinfo>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_112
 #if defined(TEST_112)
-#   include <unordered_set>
+#   include <unordered_map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_113
 #if defined(TEST_113)
-#   include <utility>
+#   include <unordered_set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_114
 #if defined(TEST_114)
-#   include <valarray>
+#   include <utility>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_115
 #if defined(TEST_115)
-#   include <variant>
+#   include <valarray>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_116
 #if defined(TEST_116)
-#   include <vector>
+#   include <variant>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_117
 #if defined(TEST_117)
-#   include <version>
+#   include <vector>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_120
-#if defined(TEST_120) && __cplusplus >= 201103L
-#   include <experimental/algorithm>
+// RUN: %{build} -DTEST_118
+#if defined(TEST_118)
+#   include <version>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_121
-#if defined(TEST_121) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
-#   include <experimental/coroutine>
+#if defined(TEST_121) && __cplusplus >= 201103L
+#   include <experimental/algorithm>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_122
-#if defined(TEST_122) && __cplusplus >= 201103L
-#   include <experimental/deque>
+#if defined(TEST_122) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
+#   include <experimental/coroutine>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_123
 #if defined(TEST_123) && __cplusplus >= 201103L
-#   include <experimental/forward_list>
+#   include <experimental/deque>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_124
 #if defined(TEST_124) && __cplusplus >= 201103L
-#   include <experimental/functional>
+#   include <experimental/forward_list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_125
 #if defined(TEST_125) && __cplusplus >= 201103L
-#   include <experimental/iterator>
+#   include <experimental/functional>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_126
 #if defined(TEST_126) && __cplusplus >= 201103L
-#   include <experimental/list>
+#   include <experimental/iterator>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_127
 #if defined(TEST_127) && __cplusplus >= 201103L
-#   include <experimental/map>
+#   include <experimental/list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_128
 #if defined(TEST_128) && __cplusplus >= 201103L
-#   include <experimental/memory_resource>
+#   include <experimental/map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_129
 #if defined(TEST_129) && __cplusplus >= 201103L
-#   include <experimental/propagate_const>
+#   include <experimental/memory_resource>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_130
-#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
-#   include <experimental/regex>
+#if defined(TEST_130) && __cplusplus >= 201103L
+#   include <experimental/propagate_const>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_131
-#if defined(TEST_131) && __cplusplus >= 201103L
-#   include <experimental/set>
+#if defined(TEST_131) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
+#   include <experimental/regex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_132
 #if defined(TEST_132) && __cplusplus >= 201103L
-#   include <experimental/simd>
+#   include <experimental/set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_133
 #if defined(TEST_133) && __cplusplus >= 201103L
-#   include <experimental/string>
+#   include <experimental/simd>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_134
 #if defined(TEST_134) && __cplusplus >= 201103L
-#   include <experimental/type_traits>
+#   include <experimental/string>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_135
 #if defined(TEST_135) && __cplusplus >= 201103L
-#   include <experimental/unordered_map>
+#   include <experimental/type_traits>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_136
 #if defined(TEST_136) && __cplusplus >= 201103L
-#   include <experimental/unordered_set>
+#   include <experimental/unordered_map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_137
 #if defined(TEST_137) && __cplusplus >= 201103L
-#   include <experimental/utility>
+#   include <experimental/unordered_set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_138
 #if defined(TEST_138) && __cplusplus >= 201103L
-#   include <experimental/vector>
+#   include <experimental/utility>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_139
-#if defined(TEST_139)
-#   include <ext/hash_map>
+#if defined(TEST_139) && __cplusplus >= 201103L
+#   include <experimental/vector>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_140
 #if defined(TEST_140)
+#   include <ext/hash_map>
+    using HandlerType = decltype(std::__libcpp_verbose_abort);
+#endif
+
+// RUN: %{build} -DTEST_141
+#if defined(TEST_141)
 #   include <ext/hash_set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif

diff  --git a/libcxx/test/libcxx/clang_tidy.sh.cpp b/libcxx/test/libcxx/clang_tidy.sh.cpp
index a3dcc57567b06..23c523ffc70d4 100644
--- a/libcxx/test/libcxx/clang_tidy.sh.cpp
+++ b/libcxx/test/libcxx/clang_tidy.sh.cpp
@@ -91,6 +91,7 @@ END-SCRIPT
 #include <errno.h>
 #include <exception>
 #include <execution>
+#include <expected>
 #include <fenv.h>
 #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
 #   include <filesystem>

diff  --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp
index 4a55dcaeb777a..0bb3c9c0e5c0a 100644
--- a/libcxx/test/libcxx/double_include.sh.cpp
+++ b/libcxx/test/libcxx/double_include.sh.cpp
@@ -93,6 +93,7 @@ END-SCRIPT
 #include <errno.h>
 #include <exception>
 #include <execution>
+#include <expected>
 #include <fenv.h>
 #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
 #   include <filesystem>

diff  --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
index a21524bb133a2..f9a151dae5ddb 100644
--- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
@@ -139,6 +139,8 @@ TEST_MACROS();
 TEST_MACROS();
 #include <execution>
 TEST_MACROS();
+#include <expected>
+TEST_MACROS();
 #include <fenv.h>
 TEST_MACROS();
 #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)

diff  --git a/libcxx/test/libcxx/modules_include.sh.cpp b/libcxx/test/libcxx/modules_include.sh.cpp
index 7e80eed2da827..dfec3792e25df 100644
--- a/libcxx/test/libcxx/modules_include.sh.cpp
+++ b/libcxx/test/libcxx/modules_include.sh.cpp
@@ -235,382 +235,386 @@ END-SCRIPT
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_46
 #if defined(TEST_46)
-#include <fenv.h>
+#include <expected>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_47
-#if defined(TEST_47) && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-#include <filesystem>
+#if defined(TEST_47)
+#include <fenv.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_48
-#if defined(TEST_48)
-#include <float.h>
+#if defined(TEST_48) && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+#include <filesystem>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_49
 #if defined(TEST_49)
-#include <format>
+#include <float.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_50
 #if defined(TEST_50)
-#include <forward_list>
+#include <format>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_51
-#if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
-#include <fstream>
+#if defined(TEST_51)
+#include <forward_list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_52
-#if defined(TEST_52)
-#include <functional>
+#if defined(TEST_52) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_FSTREAM)
+#include <fstream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_53
-#if defined(TEST_53) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <future>
+#if defined(TEST_53)
+#include <functional>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_54
-#if defined(TEST_54)
-#include <initializer_list>
+#if defined(TEST_54) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <future>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_55
 #if defined(TEST_55)
-#include <inttypes.h>
+#include <initializer_list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_56
-#if defined(TEST_56) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <iomanip>
+#if defined(TEST_56)
+#include <inttypes.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_57
 #if defined(TEST_57) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <ios>
+#include <iomanip>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_58
-#if defined(TEST_58)
-#include <iosfwd>
+#if defined(TEST_58) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <ios>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_59
-#if defined(TEST_59) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <iostream>
+#if defined(TEST_59)
+#include <iosfwd>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_60
 #if defined(TEST_60) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <istream>
+#include <iostream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_61
-#if defined(TEST_61)
-#include <iterator>
+#if defined(TEST_61) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <istream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_62
-#if defined(TEST_62) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <latch>
+#if defined(TEST_62)
+#include <iterator>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_63
-#if defined(TEST_63)
-#include <limits>
+#if defined(TEST_63) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <latch>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_64
 #if defined(TEST_64)
-#include <limits.h>
+#include <limits>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_65
 #if defined(TEST_65)
-#include <list>
+#include <limits.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_66
-#if defined(TEST_66) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <locale>
+#if defined(TEST_66)
+#include <list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_67
 #if defined(TEST_67) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <locale.h>
+#include <locale>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_68
-#if defined(TEST_68)
-#include <map>
+#if defined(TEST_68) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <locale.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_69
 #if defined(TEST_69)
-#include <math.h>
+#include <map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_70
 #if defined(TEST_70)
-#include <memory>
+#include <math.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_71
 #if defined(TEST_71)
-#include <memory_resource>
+#include <memory>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_72
-#if defined(TEST_72) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <mutex>
+#if defined(TEST_72)
+#include <memory_resource>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_73
-#if defined(TEST_73)
-#include <new>
+#if defined(TEST_73) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <mutex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_74
 #if defined(TEST_74)
-#include <numbers>
+#include <new>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_75
 #if defined(TEST_75)
-#include <numeric>
+#include <numbers>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_76
 #if defined(TEST_76)
-#include <optional>
+#include <numeric>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_77
-#if defined(TEST_77) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <ostream>
+#if defined(TEST_77)
+#include <optional>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_78
-#if defined(TEST_78)
-#include <queue>
+#if defined(TEST_78) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <ostream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_79
 #if defined(TEST_79)
-#include <random>
+#include <queue>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_80
 #if defined(TEST_80)
-#include <ranges>
+#include <random>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_81
 #if defined(TEST_81)
-#include <ratio>
+#include <ranges>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_82
-#if defined(TEST_82) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <regex>
+#if defined(TEST_82)
+#include <ratio>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_83
-#if defined(TEST_83)
-#include <scoped_allocator>
+#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <regex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_84
-#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <semaphore>
+#if defined(TEST_84)
+#include <scoped_allocator>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_85
-#if defined(TEST_85)
-#include <set>
+#if defined(TEST_85) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <semaphore>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_86
 #if defined(TEST_86)
-#include <setjmp.h>
+#include <set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_87
-#if defined(TEST_87) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <shared_mutex>
+#if defined(TEST_87)
+#include <setjmp.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_88
-#if defined(TEST_88)
-#include <span>
+#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <shared_mutex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_89
-#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <sstream>
+#if defined(TEST_89)
+#include <span>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_90
-#if defined(TEST_90)
-#include <stack>
+#if defined(TEST_90) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <sstream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_91
-#if defined(TEST_91) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <stdatomic.h>
+#if defined(TEST_91)
+#include <stack>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_92
-#if defined(TEST_92)
-#include <stdbool.h>
+#if defined(TEST_92) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <stdatomic.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_93
 #if defined(TEST_93)
-#include <stddef.h>
+#include <stdbool.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_94
 #if defined(TEST_94)
-#include <stdexcept>
+#include <stddef.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_95
 #if defined(TEST_95)
-#include <stdint.h>
+#include <stdexcept>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_96
 #if defined(TEST_96)
-#include <stdio.h>
+#include <stdint.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_97
 #if defined(TEST_97)
-#include <stdlib.h>
+#include <stdio.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_98
-#if defined(TEST_98) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <streambuf>
+#if defined(TEST_98)
+#include <stdlib.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_99
-#if defined(TEST_99)
-#include <string>
+#if defined(TEST_99) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <streambuf>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_100
 #if defined(TEST_100)
-#include <string.h>
+#include <string>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_101
 #if defined(TEST_101)
-#include <string_view>
+#include <string.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_102
-#if defined(TEST_102) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <strstream>
+#if defined(TEST_102)
+#include <string_view>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_103
-#if defined(TEST_103)
-#include <system_error>
+#if defined(TEST_103) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <strstream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_104
 #if defined(TEST_104)
-#include <tgmath.h>
+#include <system_error>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_105
-#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <thread>
+#if defined(TEST_105)
+#include <tgmath.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_106
-#if defined(TEST_106)
-#include <tuple>
+#if defined(TEST_106) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <thread>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_107
 #if defined(TEST_107)
-#include <type_traits>
+#include <tuple>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_108
 #if defined(TEST_108)
-#include <typeindex>
+#include <type_traits>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_109
 #if defined(TEST_109)
-#include <typeinfo>
+#include <typeindex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_110
 #if defined(TEST_110)
-#include <uchar.h>
+#include <typeinfo>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_111
 #if defined(TEST_111)
-#include <unordered_map>
+#include <uchar.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_112
 #if defined(TEST_112)
-#include <unordered_set>
+#include <unordered_map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_113
 #if defined(TEST_113)
-#include <utility>
+#include <unordered_set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_114
 #if defined(TEST_114)
-#include <valarray>
+#include <utility>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_115
 #if defined(TEST_115)
-#include <variant>
+#include <valarray>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_116
 #if defined(TEST_116)
-#include <vector>
+#include <variant>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_117
 #if defined(TEST_117)
-#include <version>
+#include <vector>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_118
-#if defined(TEST_118) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-#include <wchar.h>
+#if defined(TEST_118)
+#include <version>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_119
 #if defined(TEST_119) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-#include <wctype.h>
+#include <wchar.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_120
-#if defined(TEST_120) && __cplusplus >= 201103L
-#include <experimental/algorithm>
+#if defined(TEST_120) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+#include <wctype.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_121
-#if defined(TEST_121) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
-#include <experimental/coroutine>
+#if defined(TEST_121) && __cplusplus >= 201103L
+#include <experimental/algorithm>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_122
-#if defined(TEST_122) && __cplusplus >= 201103L
-#include <experimental/deque>
+#if defined(TEST_122) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
+#include <experimental/coroutine>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_123
 #if defined(TEST_123) && __cplusplus >= 201103L
-#include <experimental/forward_list>
+#include <experimental/deque>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_124
 #if defined(TEST_124) && __cplusplus >= 201103L
-#include <experimental/functional>
+#include <experimental/forward_list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_125
 #if defined(TEST_125) && __cplusplus >= 201103L
-#include <experimental/iterator>
+#include <experimental/functional>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_126
 #if defined(TEST_126) && __cplusplus >= 201103L
-#include <experimental/list>
+#include <experimental/iterator>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_127
 #if defined(TEST_127) && __cplusplus >= 201103L
-#include <experimental/map>
+#include <experimental/list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_128
 #if defined(TEST_128) && __cplusplus >= 201103L
-#include <experimental/memory_resource>
+#include <experimental/map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_129
 #if defined(TEST_129) && __cplusplus >= 201103L
-#include <experimental/propagate_const>
+#include <experimental/memory_resource>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_130
-#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
-#include <experimental/regex>
+#if defined(TEST_130) && __cplusplus >= 201103L
+#include <experimental/propagate_const>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_131
-#if defined(TEST_131) && __cplusplus >= 201103L
-#include <experimental/set>
+#if defined(TEST_131) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
+#include <experimental/regex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_132
 #if defined(TEST_132) && __cplusplus >= 201103L
-#include <experimental/simd>
+#include <experimental/set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_133
 #if defined(TEST_133) && __cplusplus >= 201103L
-#include <experimental/string>
+#include <experimental/simd>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_134
 #if defined(TEST_134) && __cplusplus >= 201103L
-#include <experimental/type_traits>
+#include <experimental/string>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_135
 #if defined(TEST_135) && __cplusplus >= 201103L
-#include <experimental/unordered_map>
+#include <experimental/type_traits>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_136
 #if defined(TEST_136) && __cplusplus >= 201103L
-#include <experimental/unordered_set>
+#include <experimental/unordered_map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_137
 #if defined(TEST_137) && __cplusplus >= 201103L
-#include <experimental/utility>
+#include <experimental/unordered_set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_138
 #if defined(TEST_138) && __cplusplus >= 201103L
-#include <experimental/vector>
+#include <experimental/utility>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_139
-#if defined(TEST_139)
-#include <ext/hash_map>
+#if defined(TEST_139) && __cplusplus >= 201103L
+#include <experimental/vector>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_140
 #if defined(TEST_140)
+#include <ext/hash_map>
+#endif
+// RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_141
+#if defined(TEST_141)
 #include <ext/hash_set>
 #endif
 // GENERATED-MARKER

diff  --git a/libcxx/test/libcxx/nasty_macros.compile.pass.cpp b/libcxx/test/libcxx/nasty_macros.compile.pass.cpp
index 43845ea042b43..d2d875f955b76 100644
--- a/libcxx/test/libcxx/nasty_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/nasty_macros.compile.pass.cpp
@@ -212,6 +212,7 @@ END-SCRIPT
 #include <errno.h>
 #include <exception>
 #include <execution>
+#include <expected>
 #include <fenv.h>
 #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
 #   include <filesystem>

diff  --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
index 68e303bfbaa08..32bd4e66f8183 100644
--- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
+++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
@@ -90,6 +90,7 @@ END-SCRIPT
 #include <errno.h>
 #include <exception>
 #include <execution>
+#include <expected>
 #include <fenv.h>
 #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
 #   include <filesystem>

diff  --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index 075b5dde3b3c9..55a0c268a579c 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -301,6 +301,10 @@ END-SCRIPT
 #include <__coroutine/trivial_awaitables.h> // expected-error@*:* {{use of private header from outside its module: '__coroutine/trivial_awaitables.h'}}
 #include <__debug_utils/randomize_range.h> // expected-error@*:* {{use of private header from outside its module: '__debug_utils/randomize_range.h'}}
 #include <__errc> // expected-error@*:* {{use of private header from outside its module: '__errc'}}
+#include <__expected/bad_expected_access.h> // expected-error@*:* {{use of private header from outside its module: '__expected/bad_expected_access.h'}}
+#include <__expected/expected.h> // expected-error@*:* {{use of private header from outside its module: '__expected/expected.h'}}
+#include <__expected/unexpect.h> // expected-error@*:* {{use of private header from outside its module: '__expected/unexpect.h'}}
+#include <__expected/unexpected.h> // expected-error@*:* {{use of private header from outside its module: '__expected/unexpected.h'}}
 #include <__filesystem/copy_options.h> // expected-error@*:* {{use of private header from outside its module: '__filesystem/copy_options.h'}}
 #include <__filesystem/directory_entry.h> // expected-error@*:* {{use of private header from outside its module: '__filesystem/directory_entry.h'}}
 #include <__filesystem/directory_iterator.h> // expected-error@*:* {{use of private header from outside its module: '__filesystem/directory_iterator.h'}}

diff  --git a/libcxx/test/libcxx/transitive_includes.sh.cpp b/libcxx/test/libcxx/transitive_includes.sh.cpp
index 7733a42b7459a..341debc713b2f 100644
--- a/libcxx/test/libcxx/transitive_includes.sh.cpp
+++ b/libcxx/test/libcxx/transitive_includes.sh.cpp
@@ -249,312 +249,316 @@ END-SCRIPT
 #if defined(TEST_45)
 #include <execution>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_47 2> %t/header.filesystem
-#if defined(TEST_47)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_46 2> %t/header.expected
+#if defined(TEST_46)
+#include <expected>
+#endif
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_48 2> %t/header.filesystem
+#if defined(TEST_48)
 #include <filesystem>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_49 2> %t/header.format
-#if defined(TEST_49)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_50 2> %t/header.format
+#if defined(TEST_50)
 #include <format>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_50 2> %t/header.forward_list
-#if defined(TEST_50)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_51 2> %t/header.forward_list
+#if defined(TEST_51)
 #include <forward_list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_51 2> %t/header.fstream
-#if defined(TEST_51)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_52 2> %t/header.fstream
+#if defined(TEST_52)
 #include <fstream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_52 2> %t/header.functional
-#if defined(TEST_52)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_53 2> %t/header.functional
+#if defined(TEST_53)
 #include <functional>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_53 2> %t/header.future
-#if defined(TEST_53)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_54 2> %t/header.future
+#if defined(TEST_54)
 #include <future>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_54 2> %t/header.initializer_list
-#if defined(TEST_54)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_55 2> %t/header.initializer_list
+#if defined(TEST_55)
 #include <initializer_list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_56 2> %t/header.iomanip
-#if defined(TEST_56)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_57 2> %t/header.iomanip
+#if defined(TEST_57)
 #include <iomanip>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_57 2> %t/header.ios
-#if defined(TEST_57)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_58 2> %t/header.ios
+#if defined(TEST_58)
 #include <ios>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_58 2> %t/header.iosfwd
-#if defined(TEST_58)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_59 2> %t/header.iosfwd
+#if defined(TEST_59)
 #include <iosfwd>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_59 2> %t/header.iostream
-#if defined(TEST_59)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_60 2> %t/header.iostream
+#if defined(TEST_60)
 #include <iostream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_60 2> %t/header.istream
-#if defined(TEST_60)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_61 2> %t/header.istream
+#if defined(TEST_61)
 #include <istream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_61 2> %t/header.iterator
-#if defined(TEST_61)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_62 2> %t/header.iterator
+#if defined(TEST_62)
 #include <iterator>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_62 2> %t/header.latch
-#if defined(TEST_62)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_63 2> %t/header.latch
+#if defined(TEST_63)
 #include <latch>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_63 2> %t/header.limits
-#if defined(TEST_63)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_64 2> %t/header.limits
+#if defined(TEST_64)
 #include <limits>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_65 2> %t/header.list
-#if defined(TEST_65)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_66 2> %t/header.list
+#if defined(TEST_66)
 #include <list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_66 2> %t/header.locale
-#if defined(TEST_66)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_67 2> %t/header.locale
+#if defined(TEST_67)
 #include <locale>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_68 2> %t/header.map
-#if defined(TEST_68)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_69 2> %t/header.map
+#if defined(TEST_69)
 #include <map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_70 2> %t/header.memory
-#if defined(TEST_70)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_71 2> %t/header.memory
+#if defined(TEST_71)
 #include <memory>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_71 2> %t/header.memory_resource
-#if defined(TEST_71)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_72 2> %t/header.memory_resource
+#if defined(TEST_72)
 #include <memory_resource>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_72 2> %t/header.mutex
-#if defined(TEST_72)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_73 2> %t/header.mutex
+#if defined(TEST_73)
 #include <mutex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_73 2> %t/header.new
-#if defined(TEST_73)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_74 2> %t/header.new
+#if defined(TEST_74)
 #include <new>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_74 2> %t/header.numbers
-#if defined(TEST_74)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_75 2> %t/header.numbers
+#if defined(TEST_75)
 #include <numbers>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_75 2> %t/header.numeric
-#if defined(TEST_75)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_76 2> %t/header.numeric
+#if defined(TEST_76)
 #include <numeric>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_76 2> %t/header.optional
-#if defined(TEST_76)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_77 2> %t/header.optional
+#if defined(TEST_77)
 #include <optional>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_77 2> %t/header.ostream
-#if defined(TEST_77)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_78 2> %t/header.ostream
+#if defined(TEST_78)
 #include <ostream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_78 2> %t/header.queue
-#if defined(TEST_78)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_79 2> %t/header.queue
+#if defined(TEST_79)
 #include <queue>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_79 2> %t/header.random
-#if defined(TEST_79)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_80 2> %t/header.random
+#if defined(TEST_80)
 #include <random>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_80 2> %t/header.ranges
-#if defined(TEST_80)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_81 2> %t/header.ranges
+#if defined(TEST_81)
 #include <ranges>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_81 2> %t/header.ratio
-#if defined(TEST_81)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_82 2> %t/header.ratio
+#if defined(TEST_82)
 #include <ratio>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_82 2> %t/header.regex
-#if defined(TEST_82)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_83 2> %t/header.regex
+#if defined(TEST_83)
 #include <regex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_83 2> %t/header.scoped_allocator
-#if defined(TEST_83)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_84 2> %t/header.scoped_allocator
+#if defined(TEST_84)
 #include <scoped_allocator>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_84 2> %t/header.semaphore
-#if defined(TEST_84)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_85 2> %t/header.semaphore
+#if defined(TEST_85)
 #include <semaphore>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_85 2> %t/header.set
-#if defined(TEST_85)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_86 2> %t/header.set
+#if defined(TEST_86)
 #include <set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_87 2> %t/header.shared_mutex
-#if defined(TEST_87)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_88 2> %t/header.shared_mutex
+#if defined(TEST_88)
 #include <shared_mutex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_88 2> %t/header.span
-#if defined(TEST_88)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_89 2> %t/header.span
+#if defined(TEST_89)
 #include <span>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_89 2> %t/header.sstream
-#if defined(TEST_89)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_90 2> %t/header.sstream
+#if defined(TEST_90)
 #include <sstream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_90 2> %t/header.stack
-#if defined(TEST_90)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_91 2> %t/header.stack
+#if defined(TEST_91)
 #include <stack>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_94 2> %t/header.stdexcept
-#if defined(TEST_94)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_95 2> %t/header.stdexcept
+#if defined(TEST_95)
 #include <stdexcept>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_98 2> %t/header.streambuf
-#if defined(TEST_98)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_99 2> %t/header.streambuf
+#if defined(TEST_99)
 #include <streambuf>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_99 2> %t/header.string
-#if defined(TEST_99)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_100 2> %t/header.string
+#if defined(TEST_100)
 #include <string>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_101 2> %t/header.string_view
-#if defined(TEST_101)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_102 2> %t/header.string_view
+#if defined(TEST_102)
 #include <string_view>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_102 2> %t/header.strstream
-#if defined(TEST_102)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_103 2> %t/header.strstream
+#if defined(TEST_103)
 #include <strstream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_103 2> %t/header.system_error
-#if defined(TEST_103)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_104 2> %t/header.system_error
+#if defined(TEST_104)
 #include <system_error>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_105 2> %t/header.thread
-#if defined(TEST_105)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_106 2> %t/header.thread
+#if defined(TEST_106)
 #include <thread>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_106 2> %t/header.tuple
-#if defined(TEST_106)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_107 2> %t/header.tuple
+#if defined(TEST_107)
 #include <tuple>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_107 2> %t/header.type_traits
-#if defined(TEST_107)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_108 2> %t/header.type_traits
+#if defined(TEST_108)
 #include <type_traits>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_108 2> %t/header.typeindex
-#if defined(TEST_108)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_109 2> %t/header.typeindex
+#if defined(TEST_109)
 #include <typeindex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_109 2> %t/header.typeinfo
-#if defined(TEST_109)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_110 2> %t/header.typeinfo
+#if defined(TEST_110)
 #include <typeinfo>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_111 2> %t/header.unordered_map
-#if defined(TEST_111)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_112 2> %t/header.unordered_map
+#if defined(TEST_112)
 #include <unordered_map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_112 2> %t/header.unordered_set
-#if defined(TEST_112)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_113 2> %t/header.unordered_set
+#if defined(TEST_113)
 #include <unordered_set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_113 2> %t/header.utility
-#if defined(TEST_113)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_114 2> %t/header.utility
+#if defined(TEST_114)
 #include <utility>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_114 2> %t/header.valarray
-#if defined(TEST_114)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_115 2> %t/header.valarray
+#if defined(TEST_115)
 #include <valarray>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_115 2> %t/header.variant
-#if defined(TEST_115)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_116 2> %t/header.variant
+#if defined(TEST_116)
 #include <variant>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_116 2> %t/header.vector
-#if defined(TEST_116)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_117 2> %t/header.vector
+#if defined(TEST_117)
 #include <vector>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_117 2> %t/header.version
-#if defined(TEST_117)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_118 2> %t/header.version
+#if defined(TEST_118)
 #include <version>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_120 2> %t/header.experimental_algorithm
-#if defined(TEST_120)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_121 2> %t/header.experimental_algorithm
+#if defined(TEST_121)
 #include <experimental/algorithm>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_121 2> %t/header.experimental_coroutine
-#if defined(TEST_121)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_122 2> %t/header.experimental_coroutine
+#if defined(TEST_122)
 #include <experimental/coroutine>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_122 2> %t/header.experimental_deque
-#if defined(TEST_122)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_123 2> %t/header.experimental_deque
+#if defined(TEST_123)
 #include <experimental/deque>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_123 2> %t/header.experimental_forward_list
-#if defined(TEST_123)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_124 2> %t/header.experimental_forward_list
+#if defined(TEST_124)
 #include <experimental/forward_list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_124 2> %t/header.experimental_functional
-#if defined(TEST_124)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_125 2> %t/header.experimental_functional
+#if defined(TEST_125)
 #include <experimental/functional>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_125 2> %t/header.experimental_iterator
-#if defined(TEST_125)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_126 2> %t/header.experimental_iterator
+#if defined(TEST_126)
 #include <experimental/iterator>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_126 2> %t/header.experimental_list
-#if defined(TEST_126)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_127 2> %t/header.experimental_list
+#if defined(TEST_127)
 #include <experimental/list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_127 2> %t/header.experimental_map
-#if defined(TEST_127)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_128 2> %t/header.experimental_map
+#if defined(TEST_128)
 #include <experimental/map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_128 2> %t/header.experimental_memory_resource
-#if defined(TEST_128)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_129 2> %t/header.experimental_memory_resource
+#if defined(TEST_129)
 #include <experimental/memory_resource>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_129 2> %t/header.experimental_propagate_const
-#if defined(TEST_129)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_130 2> %t/header.experimental_propagate_const
+#if defined(TEST_130)
 #include <experimental/propagate_const>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_130 2> %t/header.experimental_regex
-#if defined(TEST_130)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_131 2> %t/header.experimental_regex
+#if defined(TEST_131)
 #include <experimental/regex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_131 2> %t/header.experimental_set
-#if defined(TEST_131)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_132 2> %t/header.experimental_set
+#if defined(TEST_132)
 #include <experimental/set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_132 2> %t/header.experimental_simd
-#if defined(TEST_132)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_133 2> %t/header.experimental_simd
+#if defined(TEST_133)
 #include <experimental/simd>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_133 2> %t/header.experimental_string
-#if defined(TEST_133)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_134 2> %t/header.experimental_string
+#if defined(TEST_134)
 #include <experimental/string>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_134 2> %t/header.experimental_type_traits
-#if defined(TEST_134)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_135 2> %t/header.experimental_type_traits
+#if defined(TEST_135)
 #include <experimental/type_traits>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_135 2> %t/header.experimental_unordered_map
-#if defined(TEST_135)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_136 2> %t/header.experimental_unordered_map
+#if defined(TEST_136)
 #include <experimental/unordered_map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_136 2> %t/header.experimental_unordered_set
-#if defined(TEST_136)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_137 2> %t/header.experimental_unordered_set
+#if defined(TEST_137)
 #include <experimental/unordered_set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_137 2> %t/header.experimental_utility
-#if defined(TEST_137)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_138 2> %t/header.experimental_utility
+#if defined(TEST_138)
 #include <experimental/utility>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_138 2> %t/header.experimental_vector
-#if defined(TEST_138)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_139 2> %t/header.experimental_vector
+#if defined(TEST_139)
 #include <experimental/vector>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_139 2> %t/header.ext_hash_map
-#if defined(TEST_139)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_140 2> %t/header.ext_hash_map
+#if defined(TEST_140)
 #include <ext/hash_map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_140 2> %t/header.ext_hash_set
-#if defined(TEST_140)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_141 2> %t/header.ext_hash_set
+#if defined(TEST_141)
 #include <ext/hash_set>
 #endif
 // RUN: %{python} %S/transitive_includes_to_csv.py %t > %t/transitive_includes.csv

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index c3eff22f1fee6..4064fb77c8132 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -202,6 +202,13 @@ exception cstdlib
 exception type_traits
 exception version
 execution version
+expected cstddef
+expected cstdlib
+expected exception
+expected initializer_list
+expected new
+expected type_traits
+expected version
 experimental/algorithm algorithm
 experimental/algorithm cstddef
 experimental/algorithm type_traits

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index 0ab039f113f14..aa6fc0c95e169 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -202,6 +202,13 @@ exception cstdlib
 exception type_traits
 exception version
 execution version
+expected cstddef
+expected cstdlib
+expected exception
+expected initializer_list
+expected new
+expected type_traits
+expected version
 experimental/algorithm algorithm
 experimental/algorithm cstddef
 experimental/algorithm type_traits

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index 491b28707c291..e2ef4a2d8d8f3 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -202,6 +202,13 @@ exception cstdlib
 exception type_traits
 exception version
 execution version
+expected cstddef
+expected cstdlib
+expected exception
+expected initializer_list
+expected new
+expected type_traits
+expected version
 experimental/algorithm algorithm
 experimental/algorithm cstddef
 experimental/algorithm type_traits

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 491b28707c291..e2ef4a2d8d8f3 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -202,6 +202,13 @@ exception cstdlib
 exception type_traits
 exception version
 execution version
+expected cstddef
+expected cstdlib
+expected exception
+expected initializer_list
+expected new
+expected type_traits
+expected version
 experimental/algorithm algorithm
 experimental/algorithm cstddef
 experimental/algorithm type_traits

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index 1f3798909e533..91a829ab3ed93 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -214,6 +214,13 @@ exception cstdlib
 exception type_traits
 exception version
 execution version
+expected cstddef
+expected cstdlib
+expected exception
+expected initializer_list
+expected new
+expected type_traits
+expected version
 experimental/algorithm algorithm
 experimental/algorithm cstddef
 experimental/algorithm type_traits

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx2b.csv b/libcxx/test/libcxx/transitive_includes/cxx2b.csv
index bcc949bc4233a..d2b83e42cb449 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx2b.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx2b.csv
@@ -168,6 +168,13 @@ exception cstdlib
 exception type_traits
 exception version
 execution version
+expected cstddef
+expected cstdlib
+expected exception
+expected initializer_list
+expected new
+expected type_traits
+expected version
 experimental/algorithm algorithm
 experimental/algorithm cstddef
 experimental/algorithm type_traits

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.expected/assert.arrow.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/assert.arrow.pass.cpp
new file mode 100644
index 0000000000000..82fb35a022785
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/assert.arrow.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+// constexpr const T* operator->() const noexcept;
+// constexpr T* operator->() noexcept;
+//
+// Preconditions: has_value() is true.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::expected<int, int> e{std::unexpect, 5};
+  TEST_LIBCPP_ASSERT_FAILURE(e.operator->(), "expected::operator-> requires the expected to contain a value");
+  TEST_LIBCPP_ASSERT_FAILURE(std::as_const(e).operator->(), "expected::operator-> requires the expected to contain a value");
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.expected/assert.deref.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/assert.deref.pass.cpp
new file mode 100644
index 0000000000000..d1ab32159d05a
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/assert.deref.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+// constexpr const T& operator*() const & noexcept;
+// constexpr T& operator*() & noexcept;
+// constexpr T&& operator*() && noexcept;
+// constexpr const T&& operator*() const && noexcept;
+//
+// Preconditions: has_value() is true.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::expected<int, int> e{std::unexpect, 5};
+  TEST_LIBCPP_ASSERT_FAILURE(*e, "expected::operator* requires the expected to contain a value");
+  TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(e), "expected::operator* requires the expected to contain a value");
+  TEST_LIBCPP_ASSERT_FAILURE(*std::move(e), "expected::operator* requires the expected to contain a value");
+  TEST_LIBCPP_ASSERT_FAILURE(*std::move(std::as_const(e)), "expected::operator* requires the expected to contain a value");
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.expected/assert.error.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/assert.error.pass.cpp
new file mode 100644
index 0000000000000..814b47d1c756f
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/assert.error.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+// constexpr const E& error() const & noexcept;
+// constexpr E& error() & noexcept;
+// constexpr E&& error() && noexcept;
+// constexpr const E&& error() const && noexcept;
+//
+// Preconditions: has_value() is false.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::expected<int, int> e{std::in_place, 5};
+  TEST_LIBCPP_ASSERT_FAILURE(e.error(), "expected::error requires the expected to contain an error");
+  TEST_LIBCPP_ASSERT_FAILURE(std::as_const(e).error(), "expected::error requires the expected to contain an error");
+  TEST_LIBCPP_ASSERT_FAILURE(std::move(e).error(), "expected::error requires the expected to contain an error");
+  TEST_LIBCPP_ASSERT_FAILURE(std::move(std::as_const(e)).error(), "expected::error requires the expected to contain an error");
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..3fd047df7134c
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+// test [[no_unique_address]] is applied to the union
+
+#include <expected>
+
+struct Empty {};
+
+static_assert(sizeof(std::expected<Empty, Empty>) == sizeof(bool));

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp
new file mode 100644
index 0000000000000..643bf4d1f2a8f
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// test libc++ noexcept extensions on operations of std::expected<T, E>
+
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../types.h"
+
+// expected();
+static_assert(std::is_nothrow_default_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_default_constructible_v<std::expected<DefaultMayThrow, int>>);
+
+// expected(const expected&)
+static_assert(std::is_nothrow_copy_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_copy_constructible_v<std::expected<CopyMayThrow, int>>);
+static_assert(!std::is_nothrow_copy_constructible_v<std::expected<int, CopyMayThrow>>);
+
+// expected(const expected<OtherT, OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<long, long>,
+              const std::expected<int, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<ConvertFromCopyIntMayThrow, long>,
+              const std::expected<int, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<long, ConvertFromCopyIntMayThrow>,
+              const std::expected<int, int>&>);
+static_assert(!std::is_nothrow_constructible_v<                                      //
+              std::expected<ConvertFromCopyIntMayThrow, ConvertFromCopyIntMayThrow>, //
+              const std::expected<int, int>&>);
+
+// expected(expected<OtherT, OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<long, long>,
+              std::expected<int, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<ConvertFromMoveIntMayThrow, long>,
+              std::expected<int, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<long, ConvertFromMoveIntMayThrow>,
+              std::expected<int, int>&&>);
+static_assert(!std::is_nothrow_constructible_v<                                      //
+              std::expected<ConvertFromMoveIntMayThrow, ConvertFromMoveIntMayThrow>, //
+              std::expected<int, int>&&>);
+
+// expected(U&&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<int, int>,
+              const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<ConvertFromCopyIntMayThrow, int>,
+              const int&>);
+
+// expected(const unexpected<OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<int, long>,
+              const std::unexpected<int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<int, ConvertFromCopyIntMayThrow>,
+              const std::unexpected<int>&>);
+
+// expected(unexpected<OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<int, long>,
+              std::unexpected<int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<int, ConvertFromMoveIntMayThrow>,
+              std::unexpected<int>&&>);
+
+// expected(in_place_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<int, int>,
+              std::in_place_t,
+              const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<ConvertFromCopyIntMayThrow, int>,
+              std::in_place_t,
+              const int&>);
+
+// expected(in_place_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<ConvertFromInitializerListNoexcept, int>,
+              std::in_place_t,
+              std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<ConvertFromInitializerListMayThrow, int>,
+              std::in_place_t,
+              std::initializer_list<int>>);
+
+// expected(unexpect_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<int, int>,
+              std::unexpect_t,
+              const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<int, ConvertFromCopyIntMayThrow>,
+              std::unexpect_t,
+              const int&>);
+
+// expected(unexpect_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<int, ConvertFromInitializerListNoexcept>,
+              std::unexpect_t,
+              std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<int, ConvertFromInitializerListMayThrow>,
+              std::unexpect_t,
+              std::initializer_list<int>>);
+
+// expected& operator=(const expected&)
+static_assert(std::is_nothrow_copy_assignable_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<CopyConstructMayThrow, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<CopyAssignMayThrow, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<int, CopyConstructMayThrow>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<int, CopyAssignMayThrow>>);

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.expected/value_or.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/value_or.mandates.verify.cpp
new file mode 100644
index 0000000000000..11d52aeeea455
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/value_or.mandates.verify.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+// Test the mandates
+// template<class U> constexpr T value_or(U&& v) const &;
+// Mandates: is_copy_constructible_v<T> is true and is_convertible_v<U, T> is true.
+
+// template<class U> constexpr T value_or(U&& v) &&;
+// Mandates: is_move_constructible_v<T> is true and is_convertible_v<U, T> is true.
+
+#include <expected>
+#include <utility>
+
+struct NonCopyable {
+  NonCopyable(int) {}
+  NonCopyable(const NonCopyable&) = delete;
+};
+
+struct NonMovable {
+  NonMovable(int) {}
+  NonMovable(NonMovable&&) = delete;
+};
+
+struct NotConvertibleFromInt {};
+
+void test() {
+  // const & overload
+  // !is_copy_constructible_v<T>,
+  {
+    const std::expected<NonCopyable, int> f1{5};
+    f1.value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NonCopyable, int>::value_or<int>' requested here}}
+    // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}value_type has to be copy constructible}}
+  }
+
+  // const & overload
+  // !is_convertible_v<U, T>
+  {
+    const std::expected<NotConvertibleFromInt, int> f1{std::in_place};
+    f1.value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NotConvertibleFromInt, int>::value_or<int>' requested here}}
+    //expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to value_type}}
+  }
+
+  // && overload
+  // !is_move_constructible_v<T>,
+  {
+    std::expected<NonMovable, int> f1{5};
+    std::move(f1).value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NonMovable, int>::value_or<int>' requested here}}
+    //expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}value_type has to be move constructible}}
+  }
+
+  // && overload
+  // !is_convertible_v<U, T>
+  {
+    std::expected<NotConvertibleFromInt, int> f1{std::in_place};
+    std::move(f1).value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NotConvertibleFromInt, int>::value_or<int>' requested here}}
+    //expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to value_type}}
+  }
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.unexpected/class.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.unexpected/class.mandates.verify.cpp
new file mode 100644
index 0000000000000..65446725ce485
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.unexpected/class.mandates.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// A program that instantiates the definition of unexpected for a non-object type, an array type, a specialization of unexpected, or a cv-qualified type is ill-formed.
+
+#include <expected>
+
+
+
+template class std::unexpected<int[2]>; // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<const int>; // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<int&>; // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<std::unexpected<int>>; // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<volatile int>; // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}[expected.un.general]}}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp
new file mode 100644
index 0000000000000..867b90e8bc728
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// test libc++ noexcept extensions on operations of std::unexpected<E>
+
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../types.h"
+
+// unexpected(Error&&);
+static_assert(std::is_nothrow_constructible_v< //
+              std::unexpected<int>,
+              const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::unexpected<ConvertFromCopyIntMayThrow>,
+              const int&>);
+
+
+// unexpected(in_place_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::unexpected<int>,
+              std::in_place_t,
+              const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::unexpected<ConvertFromCopyIntMayThrow>,
+              std::in_place_t,
+              const int&>);
+
+// unexpected(in_place_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::unexpected<ConvertFromInitializerListNoexcept>,
+              std::in_place_t,
+              std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::unexpected<ConvertFromInitializerListMayThrow>,
+              std::in_place_t,
+              std::initializer_list<int>>);

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.unexpected/swap.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.unexpected/swap.mandates.verify.cpp
new file mode 100644
index 0000000000000..2ac0644430d05
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.unexpected/swap.mandates.verify.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+// Test the mandates
+// constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
+// Mandates: is_swappable_v<E> is true.
+
+#include <expected>
+
+struct Foo {};
+
+void swap(Foo&, Foo&) = delete;
+
+void test() {
+  std::unexpected<Foo> f1{Foo{}};
+  f1.swap(f1); // expected-note{{in instantiation of member function 'std::unexpected<Foo>::swap' requested here}}
+  // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}unexpected::swap requires is_swappable_v<E> to be true}}
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.void/assert.deref.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/assert.deref.pass.cpp
new file mode 100644
index 0000000000000..d75f15d91be98
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.void/assert.deref.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+// constexpr void operator*() const noexcept;
+//
+// Preconditions: has_value() is true.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::expected<void, int> e{std::unexpect, 5};
+  TEST_LIBCPP_ASSERT_FAILURE(*e, "expected::operator* requires the expected to contain a value");
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.void/assert.error.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/assert.error.pass.cpp
new file mode 100644
index 0000000000000..1e20cc54be4b3
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.void/assert.error.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+// constexpr const E& error() const & noexcept;
+// constexpr E& error() & noexcept;
+// constexpr E&& error() && noexcept;
+// constexpr const E&& error() const && noexcept;
+//
+// Preconditions: has_value() is false.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  std::expected<void, int> e{std::in_place};
+  TEST_LIBCPP_ASSERT_FAILURE(e.error(), "expected::error requires the expected to contain an error");
+  TEST_LIBCPP_ASSERT_FAILURE(std::as_const(e).error(), "expected::error requires the expected to contain an error");
+  TEST_LIBCPP_ASSERT_FAILURE(std::move(e).error(), "expected::error requires the expected to contain an error");
+  TEST_LIBCPP_ASSERT_FAILURE(std::move(std::as_const(e)).error(), "expected::error requires the expected to contain an error");
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..1ad2aa125c295
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.void/no_unique_address.compile.pass.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+// test [[no_unique_address]] is applied to the union
+
+#include <expected>
+
+struct Empty {};
+
+static_assert(sizeof(std::expected<void, Empty>) == sizeof(bool));

diff  --git a/libcxx/test/libcxx/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp
new file mode 100644
index 0000000000000..3ecbc0abec059
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// test libc++ noexcept extensions on operations of std::expected<void, E>
+
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../types.h"
+
+// expected(const expected&)
+static_assert(std::is_nothrow_copy_constructible_v<std::expected<void, int>>);
+static_assert(!std::is_nothrow_copy_constructible_v<std::expected<void, CopyMayThrow>>);
+
+
+// expected(const expected<OtherT, OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<void, long>,
+              const std::expected<void, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromCopyIntMayThrow>,
+              const std::expected<void, int>&>);
+
+
+// expected(expected<OtherT, OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<void, long>,
+              std::expected<void, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromMoveIntMayThrow>,
+              std::expected<void, int>&&>);
+
+// expected(const unexpected<OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<void, long>,
+              const std::unexpected<int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromCopyIntMayThrow>,
+              const std::unexpected<int>&>);
+
+// expected(unexpected<OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<void, long>,
+              std::unexpected<int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromMoveIntMayThrow>,
+              std::unexpected<int>&&>);
+
+
+// expected(unexpect_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<void, int>,
+              std::unexpect_t,
+              const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromCopyIntMayThrow>,
+              std::unexpect_t,
+              const int&>);
+
+// expected(unexpect_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromInitializerListNoexcept>,
+              std::unexpect_t,
+              std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+              std::expected<void, ConvertFromInitializerListMayThrow>,
+              std::unexpect_t,
+              std::initializer_list<int>>);
+
+// expected& operator=(const expected&)
+static_assert(std::is_nothrow_copy_assignable_v<std::expected<void, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<void, CopyConstructMayThrow>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<void, CopyAssignMayThrow>>);

diff  --git a/libcxx/test/libcxx/utilities/expected/types.h b/libcxx/test/libcxx/utilities/expected/types.h
new file mode 100644
index 0000000000000..52b4e6e6c1ba0
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/types.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_LIBCXX_UTILITIES_EXPECTED_TYPES_H
+#define TEST_LIBCXX_UTILITIES_EXPECTED_TYPES_H
+
+#include <initializer_list>
+
+struct DefaultMayThrow {
+  DefaultMayThrow();
+};
+
+struct CopyMayThrow {
+  CopyMayThrow(const CopyMayThrow&);
+};
+
+struct ConvertFromCopyIntMayThrow {
+  ConvertFromCopyIntMayThrow(const int&);
+  ConvertFromCopyIntMayThrow(int&&) noexcept;
+};
+
+struct ConvertFromMoveIntMayThrow {
+  ConvertFromMoveIntMayThrow(const int&) noexcept;
+  ConvertFromMoveIntMayThrow(int&&);
+};
+
+struct ConvertFromInitializerListNoexcept {
+  ConvertFromInitializerListNoexcept(std::initializer_list<int>) noexcept;
+};
+
+struct ConvertFromInitializerListMayThrow {
+  ConvertFromInitializerListMayThrow(std::initializer_list<int>);
+};
+
+struct CopyConstructMayThrow {
+  CopyConstructMayThrow(const CopyConstructMayThrow&);
+  CopyConstructMayThrow& operator=(CopyConstructMayThrow const&) noexcept;
+};
+
+struct CopyAssignMayThrow {
+  CopyAssignMayThrow(const CopyAssignMayThrow&) noexcept;
+  CopyAssignMayThrow& operator=(CopyAssignMayThrow const&);
+};
+
+
+#endif // TEST_LIBCXX_UTILITIES_EXPECTED_TYPES_H

diff  --git a/libcxx/test/libcxx/utilities/expected/version.pass.cpp b/libcxx/test/libcxx/utilities/expected/version.pass.cpp
new file mode 100644
index 0000000000000..d9d45fe1a0eb1
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/version.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <expected>
+
+#include <expected>
+
+#include "test_macros.h"
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main(int, char**)
+{
+
+  return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
new file mode 100644
index 0000000000000..4872981be89e0
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <expected>
+
+// Test the feature test macros defined by <expected>
+
+/*  Constant              Value
+    __cpp_lib_expected    202202L [C++2b]
+*/
+
+#include <expected>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER > 20
+
+# ifndef __cpp_lib_expected
+#   error "__cpp_lib_expected should be defined in c++2b"
+# endif
+# if __cpp_lib_expected != 202202L
+#   error "__cpp_lib_expected should have the value 202202L in c++2b"
+# endif
+
+#endif // TEST_STD_VER > 20
+

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 50632e68e1d66..9026cd120bbd3 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -76,6 +76,7 @@
     __cpp_lib_exchange_function                    201304L [C++14]
     __cpp_lib_execution                            201603L [C++17]
                                                    201902L [C++20]
+    __cpp_lib_expected                             202202L [C++2b]
     __cpp_lib_filesystem                           201703L [C++17]
     __cpp_lib_format                               202106L [C++20]
     __cpp_lib_forward_like                         202207L [C++2b]
@@ -416,6 +417,10 @@
 #   error "__cpp_lib_execution should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_filesystem
 #   error "__cpp_lib_filesystem should not be defined before c++17"
 # endif
@@ -1059,6 +1064,10 @@
 #   error "__cpp_lib_execution should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_filesystem
 #   error "__cpp_lib_filesystem should not be defined before c++17"
 # endif
@@ -1807,6 +1816,10 @@
 #   endif
 # endif
 
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
 # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
 #   ifndef __cpp_lib_filesystem
 #     error "__cpp_lib_filesystem should be defined in c++17"
@@ -2840,6 +2853,10 @@
 #   endif
 # endif
 
+# ifdef __cpp_lib_expected
+#   error "__cpp_lib_expected should not be defined before c++2b"
+# endif
+
 # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
 #   ifndef __cpp_lib_filesystem
 #     error "__cpp_lib_filesystem should be defined in c++20"
@@ -4071,6 +4088,13 @@
 #   endif
 # endif
 
+# ifndef __cpp_lib_expected
+#   error "__cpp_lib_expected should be defined in c++2b"
+# endif
+# if __cpp_lib_expected != 202202L
+#   error "__cpp_lib_expected should have the value 202202L in c++2b"
+# endif
+
 # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
 #   ifndef __cpp_lib_filesystem
 #     error "__cpp_lib_filesystem should be defined in c++2b"

diff  --git a/libcxx/test/std/utilities/expected/expected.bad/ctor.error.pass.cpp b/libcxx/test/std/utilities/expected/expected.bad/ctor.error.pass.cpp
new file mode 100644
index 0000000000000..67a91b99f26c1
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.bad/ctor.error.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// explicit bad_expected_access(E e);
+
+// Effects: Initializes unex with std::move(e).
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+#include "test_macros.h"
+#include "MoveOnly.h"
+
+// test explicit
+static_assert(std::convertible_to<int, int>);
+static_assert(!std::convertible_to<int, std::bad_expected_access<int>>);
+
+int main(int, char**) {
+  std::bad_expected_access<MoveOnly> b(MoveOnly{3});
+  assert(b.error().get() == 3);
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.bad/error.member.pass.cpp b/libcxx/test/std/utilities/expected/expected.bad/error.member.pass.cpp
new file mode 100644
index 0000000000000..4e1e2ea864de2
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.bad/error.member.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// E& error() & noexcept;
+// const E& error() const & noexcept;
+// E&& error() && noexcept;
+// const E&& error() const && noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+template <class T>
+concept ErrorNoexcept =
+    requires(T&& t) {
+      { std::forward<T>(t).error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+static_assert(ErrorNoexcept<std::bad_expected_access<int>&>);
+static_assert(ErrorNoexcept<std::bad_expected_access<int> const&>);
+static_assert(ErrorNoexcept<std::bad_expected_access<int>&&>);
+static_assert(ErrorNoexcept<std::bad_expected_access<int> const&&>);
+
+void test() {
+  // &
+  {
+    std::bad_expected_access<int> e(5);
+    decltype(auto) i = e.error();
+    static_assert(std::same_as<decltype(i), int&>);
+    assert(i == 5);
+  }
+
+  // const &
+  {
+    const std::bad_expected_access<int> e(5);
+    decltype(auto) i = e.error();
+    static_assert(std::same_as<decltype(i), const int&>);
+    assert(i == 5);
+  }
+
+  // &&
+  {
+    std::bad_expected_access<int> e(5);
+    decltype(auto) i = std::move(e).error();
+    static_assert(std::same_as<decltype(i), int&&>);
+    assert(i == 5);
+  }
+
+  // const &&
+  {
+    const std::bad_expected_access<int> e(5);
+    decltype(auto) i = std::move(e).error();
+    static_assert(std::same_as<decltype(i), const int&&>);
+    assert(i == 5);
+  }
+}
+
+int main(int, char**) {
+  test();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp b/libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp
new file mode 100644
index 0000000000000..e6d050b2129d6
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// const char* what() const noexcept override;
+
+#include <expected>
+#include <utility>
+
+template <class T>
+concept WhatNoexcept =
+    requires(const T& t) {
+      { t.what() } noexcept;
+    };
+
+struct foo{};
+
+static_assert(!WhatNoexcept<foo>);
+static_assert(WhatNoexcept<std::bad_expected_access<int>>);
+static_assert(WhatNoexcept<std::bad_expected_access<foo>>);

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/assign.U.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.U.pass.cpp
new file mode 100644
index 0000000000000..09122502268f3
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.U.pass.cpp
@@ -0,0 +1,338 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+//  template<class U = T>
+//   constexpr expected& operator=(U&& v);
+//
+// Constraints:
+// - is_same_v<expected, remove_cvref_t<U>> is false; and
+// - remove_cvref_t<U> is not a specialization of unexpected; and
+// - is_constructible_v<T, U> is true; and
+// - is_assignable_v<T&, U> is true; and
+// - is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> ||
+//   is_nothrow_move_constructible_v<E> is true.
+//
+// Effects:
+// - If has_value() is true, equivalent to: val = std::forward<U>(v);
+// - Otherwise, equivalent to:
+//   reinit-expected(val, unex, std::forward<U>(v));
+//   has_val = true;
+// - Returns: *this.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotCopyConstructible {
+  NotCopyConstructible(const NotCopyConstructible&)            = delete;
+  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+// Test constraints
+static_assert(std::is_assignable_v<std::expected<int, int>&, int>);
+
+// is_same_v<expected, remove_cvref_t<U>>
+// it is true because it covered by the copy assignment
+static_assert(std::is_assignable_v<std::expected<int, int>&, std::expected<int, int>>);
+
+// remove_cvref_t<U> is a specialization of unexpected
+// it is true because it covered the unepxected overload
+static_assert(std::is_assignable_v<std::expected<int, int>&, std::unexpected<int>>);
+
+// !is_constructible_v<T, U>
+struct NoCtorFromInt {
+  NoCtorFromInt(int) = delete;
+  NoCtorFromInt& operator=(int);
+};
+static_assert(!std::is_assignable_v<std::expected<NoCtorFromInt, int>&, int>);
+
+// !is_assignable_v<T&, U>
+struct NoAssignFromInt {
+  explicit NoAssignFromInt(int);
+  NoAssignFromInt& operator=(int) = delete;
+};
+static_assert(!std::is_assignable_v<std::expected<NoAssignFromInt, int>&, int>);
+
+template <bool moveNoexcept, bool convertNoexcept>
+struct MaybeNoexcept {
+  explicit MaybeNoexcept(int) noexcept(convertNoexcept);
+  MaybeNoexcept(MaybeNoexcept&&) noexcept(moveNoexcept);
+  MaybeNoexcept& operator=(MaybeNoexcept&&) = default;
+  MaybeNoexcept& operator=(int);
+};
+
+// !is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+// is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, int>&, int>);
+
+// is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, true>, MaybeNoexcept<false, false>>&, int>);
+
+// !is_nothrow_constructible_v<T, U> && is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<true, false>, MaybeNoexcept<false, false>>&, int>);
+
+// !is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, false>>&, int>);
+
+constexpr bool test() {
+  // If has_value() is true, equivalent to: val = std::forward<U>(v);
+  // Copy
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<Traced, int> e1(std::in_place, oldState, 5);
+    Traced u(newState, 10);
+    decltype(auto) x = (e1 = u);
+    static_assert(std::same_as<decltype(x), std::expected<Traced, int>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+    assert(oldState.copyAssignCalled);
+  }
+
+  // If has_value() is true, equivalent to: val = std::forward<U>(v);
+  // Move
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<Traced, int> e1(std::in_place, oldState, 5);
+    Traced u(newState, 10);
+    decltype(auto) x = (e1 = std::move(u));
+    static_assert(std::same_as<decltype(x), std::expected<Traced, int>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+    assert(oldState.moveAssignCalled);
+  }
+
+  // Otherwise, equivalent to:
+  //   reinit-expected(val, unex, std::forward<U>(v));
+  // is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+  // !is_nothrow_move_constructible_v<E>
+  // copy
+  //
+  //  In this case, it should call the branch
+  //    destroy_at(addressof(oldval));
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  {
+    BothMayThrow::state oldState{};
+    std::expected<MoveThrowConvNoexcept, BothMayThrow> e1(std::unexpect, oldState, 5);
+    const int i      = 10;
+    decltype(auto) x = (e1 = i);
+    static_assert(std::same_as<decltype(x), std::expected<MoveThrowConvNoexcept, BothMayThrow>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyCtorCalled);
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e1.value().copiedFromInt);
+  }
+
+  // Otherwise, equivalent to:
+  //   reinit-expected(val, unex, std::forward<U>(v));
+  // is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+  // !is_nothrow_move_constructible_v<E>
+  // move
+  //
+  //  In this case, it should call the branch
+  //    destroy_at(addressof(oldval));
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  {
+    BothMayThrow::state oldState{};
+    std::expected<MoveThrowConvNoexcept, BothMayThrow> e1(std::unexpect, oldState, 5);
+    decltype(auto) x = (e1 = 10);
+    static_assert(std::same_as<decltype(x), std::expected<MoveThrowConvNoexcept, BothMayThrow>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyCtorCalled);
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e1.value().movedFromInt);
+  }
+
+  // Otherwise, equivalent to:
+  //   reinit-expected(val, unex, std::forward<U>(v));
+  // !is_nothrow_constructible_v<T, U> && is_nothrow_move_constructible_v<T> &&
+  // !is_nothrow_move_constructible_v<E>
+  // copy
+  //
+  //  In this case, it should call the branch
+  //  T tmp(std::forward<Args>(args)...);
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::move(tmp));
+  {
+    BothMayThrow::state oldState{};
+    std::expected<MoveNoexceptConvThrow, BothMayThrow> e1(std::unexpect, oldState, 5);
+    const int i      = 10;
+    decltype(auto) x = (e1 = i);
+    static_assert(std::same_as<decltype(x), std::expected<MoveNoexceptConvThrow, BothMayThrow>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyCtorCalled);
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!e1.value().copiedFromInt);
+    assert(e1.value().movedFromTmp);
+  }
+
+  // Otherwise, equivalent to:
+  //   reinit-expected(val, unex, std::forward<U>(v));
+  // !is_nothrow_constructible_v<T, U> && is_nothrow_move_constructible_v<T> &&
+  // !is_nothrow_move_constructible_v<E>
+  // move
+  //
+  //  In this case, it should call the branch
+  //  T tmp(std::forward<Args>(args)...);
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::move(tmp));
+  {
+    BothMayThrow::state oldState{};
+    std::expected<MoveNoexceptConvThrow, BothMayThrow> e1(std::unexpect, oldState, 5);
+    decltype(auto) x = (e1 = 10);
+    static_assert(std::same_as<decltype(x), std::expected<MoveNoexceptConvThrow, BothMayThrow>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyCtorCalled);
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!e1.value().copiedFromInt);
+    assert(e1.value().movedFromTmp);
+  }
+
+  // Otherwise, equivalent to:
+  //   reinit-expected(val, unex, std::forward<U>(v));
+  // !is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+  // is_nothrow_move_constructible_v<E>
+  // copy
+  //
+  //  In this case, it should call the branch
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  {
+    TracedNoexcept::state oldState{};
+    std::expected<BothMayThrow, TracedNoexcept> e1(std::unexpect, oldState, 5);
+    const int i      = 10;
+    decltype(auto) x = (e1 = i);
+    static_assert(std::same_as<decltype(x), std::expected<BothMayThrow, TracedNoexcept>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyCtorCalled);
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e1.value().copiedFromInt);
+  }
+
+  // Otherwise, equivalent to:
+  //   reinit-expected(val, unex, std::forward<U>(v));
+  // !is_nothrow_constructible_v<T, U> && !is_nothrow_move_constructible_v<T> &&
+  // is_nothrow_move_constructible_v<E>
+  // move
+  //
+  //  In this case, it should call the branch
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  {
+    TracedNoexcept::state oldState{};
+    std::expected<BothMayThrow, TracedNoexcept> e1(std::unexpect, oldState, 5);
+    decltype(auto) x = (e1 = 10);
+    static_assert(std::same_as<decltype(x), std::expected<BothMayThrow, TracedNoexcept>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyCtorCalled);
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e1.value().movedFromInt);
+  }
+
+  // Test default template argument.
+  // Without it, the template parameter cannot be deduced from an initializer list
+  {
+    struct Bar {
+      int i;
+      int j;
+      constexpr Bar(int ii, int jj) : i(ii), j(jj) {}
+    };
+
+    std::expected<Bar, int> e({5, 6});
+    e = {7, 8};
+    assert(e.value().i == 7);
+    assert(e.value().j == 8);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<ThrowOnConvert, int> e1(std::unexpect, 5);
+  try {
+    e1 = 10;
+    assert(false);
+  } catch (Except) {
+    assert(!e1.has_value());
+    assert(e1.error() == 5);
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/assign.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.copy.pass.cpp
new file mode 100644
index 0000000000000..d4496bac85c86
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.copy.pass.cpp
@@ -0,0 +1,291 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr expected& operator=(const expected& rhs);
+//
+// Effects:
+// - If this->has_value() && rhs.has_value() is true, equivalent to val = *rhs.
+// - Otherwise, if this->has_value() is true, equivalent to:
+//  reinit-expected(unex, val, rhs.error())
+// - Otherwise, if rhs.has_value() is true, equivalent to:
+//  reinit-expected(val, unex, *rhs)
+// - Otherwise, equivalent to unex = rhs.error().
+//
+// - Then, if no exception was thrown, equivalent to: has_val = rhs.has_value(); return *this;
+//
+// Returns: *this.
+//
+// Remarks: This operator is defined as deleted unless:
+// - is_copy_assignable_v<T> is true and
+// - is_copy_constructible_v<T> is true and
+// - is_copy_assignable_v<E> is true and
+// - is_copy_constructible_v<E> is true and
+// - is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotCopyConstructible {
+  NotCopyConstructible(const NotCopyConstructible&)            = delete;
+  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow const&)            = default;
+  MoveMayThrow& operator=(const MoveMayThrow&) = default;
+  MoveMayThrow(MoveMayThrow&&) noexcept(false) {}
+  MoveMayThrow& operator=(MoveMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test constraints
+static_assert(std::is_copy_assignable_v<std::expected<int, int>>);
+
+// !is_copy_assignable_v<T>
+static_assert(!std::is_copy_assignable_v<std::expected<NotCopyAssignable, int>>);
+
+// !is_copy_constructible_v<T>
+static_assert(!std::is_copy_assignable_v<std::expected<NotCopyConstructible, int>>);
+
+// !is_copy_assignable_v<E>
+static_assert(!std::is_copy_assignable_v<std::expected<int, NotCopyAssignable>>);
+
+// !is_copy_constructible_v<E>
+static_assert(!std::is_copy_assignable_v<std::expected<int, NotCopyConstructible>>);
+
+// !is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>
+static_assert(std::is_copy_assignable_v<std::expected<MoveMayThrow, int>>);
+
+// is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(std::is_copy_assignable_v<std::expected<int, MoveMayThrow>>);
+
+// !is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_copy_assignable_v<std::expected<MoveMayThrow, MoveMayThrow>>);
+
+constexpr bool test() {
+  // If this->has_value() && rhs.has_value() is true, equivalent to val = *rhs.
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<Traced, int> e1(std::in_place, oldState, 5);
+    const std::expected<Traced, int> e2(std::in_place, newState, 10);
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<Traced, int>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+    assert(oldState.copyAssignCalled);
+  }
+
+  // - Otherwise, if this->has_value() is true, equivalent to:
+  // reinit-expected(unex, val, rhs.error())
+  //  E move is not noexcept
+  //  In this case, it should call the branch
+  //
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  //
+  {
+    TracedNoexcept::state oldState{};
+    Traced::state newState{};
+    std::expected<TracedNoexcept, Traced> e1(std::in_place, oldState, 5);
+    const std::expected<TracedNoexcept, Traced> e2(std::unexpect, newState, 10);
+
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<TracedNoexcept, Traced>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+
+    assert(!oldState.copyAssignCalled);
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(newState.copyCtorCalled);
+    assert(!newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // - Otherwise, if this->has_value() is true, equivalent to:
+  // reinit-expected(unex, val, rhs.error())
+  //  E move is noexcept
+  //  In this case, it should call the branch
+  //
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::forward<Args>(args)...);
+  //
+  {
+    Traced::state oldState{};
+    TracedNoexcept::state newState{};
+    std::expected<Traced, TracedNoexcept> e1(std::in_place, oldState, 5);
+    const std::expected<Traced, TracedNoexcept> e2(std::unexpect, newState, 10);
+
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<Traced, TracedNoexcept>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+
+    assert(!oldState.copyAssignCalled);
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(newState.copyCtorCalled);
+    assert(!newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // - Otherwise, if rhs.has_value() is true, equivalent to:
+  // reinit-expected(val, unex, *rhs)
+  //  T move is not noexcept
+  //  In this case, it should call the branch
+  //
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  //
+  {
+    TracedNoexcept::state oldState{};
+    Traced::state newState{};
+    std::expected<Traced, TracedNoexcept> e1(std::unexpect, oldState, 5);
+    const std::expected<Traced, TracedNoexcept> e2(std::in_place, newState, 10);
+
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<Traced, TracedNoexcept>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyAssignCalled);
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(newState.copyCtorCalled);
+    assert(!newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // - Otherwise, if rhs.has_value() is true, equivalent to:
+  // reinit-expected(val, unex, *rhs)
+  //  T move is noexcept
+  //  In this case, it should call the branch
+  //
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::forward<Args>(args)...);
+  //
+  {
+    Traced::state oldState{};
+    TracedNoexcept::state newState{};
+    std::expected<TracedNoexcept, Traced> e1(std::unexpect, oldState, 5);
+    const std::expected<TracedNoexcept, Traced> e2(std::in_place, newState, 10);
+
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<TracedNoexcept, Traced>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.copyAssignCalled);
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(newState.copyCtorCalled);
+    assert(!newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // Otherwise, equivalent to unex = rhs.error().
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<int, Traced> e1(std::unexpect, oldState, 5);
+    const std::expected<int, Traced> e2(std::unexpect, newState, 10);
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<int, Traced>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(oldState.copyAssignCalled);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct ThrowOnCopyMoveMayThrow {
+    ThrowOnCopyMoveMayThrow() = default;
+    ThrowOnCopyMoveMayThrow(const ThrowOnCopyMoveMayThrow&) { throw Except{}; };
+    ThrowOnCopyMoveMayThrow& operator=(const ThrowOnCopyMoveMayThrow&) = default;
+    ThrowOnCopyMoveMayThrow(ThrowOnCopyMoveMayThrow&&) noexcept(false) {}
+  };
+
+  // assign value throw on copy
+  {
+    std::expected<ThrowOnCopyMoveMayThrow, int> e1(std::unexpect, 5);
+    const std::expected<ThrowOnCopyMoveMayThrow, int> e2(std::in_place);
+    try {
+      e1 = e2;
+      assert(false);
+    } catch (Except) {
+      assert(!e1.has_value());
+      assert(e1.error() == 5);
+    }
+  }
+
+  // assign error throw on copy
+  {
+    std::expected<int, ThrowOnCopyMoveMayThrow> e1(5);
+    const std::expected<int, ThrowOnCopyMoveMayThrow> e2(std::unexpect);
+    try {
+      e1 = e2;
+      assert(false);
+    } catch (Except) {
+      assert(e1.has_value());
+      assert(e1.value() == 5);
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/assign.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.move.pass.cpp
new file mode 100644
index 0000000000000..b247ed36690a4
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.move.pass.cpp
@@ -0,0 +1,302 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr expected& operator=(expected&& rhs) noexcept(see below);
+//
+// Constraints:
+// - is_move_constructible_v<T> is true and
+// - is_move_assignable_v<T> is true and
+// - is_move_constructible_v<E> is true and
+// - is_move_assignable_v<E> is true and
+// - is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true.
+//
+// Effects:
+// - If this->has_value() && rhs.has_value() is true, equivalent to val = std::move(*rhs).
+// - Otherwise, if this->has_value() is true, equivalent to:
+//   reinit-expected(unex, val, std::move(rhs.error()))
+// - Otherwise, if rhs.has_value() is true, equivalent to:
+//   reinit-expected(val, unex, std::move(*rhs))
+// - Otherwise, equivalent to unex = std::move(rhs.error()).
+// - Then, if no exception was thrown, equivalent to: has_val = rhs.has_value(); return *this;
+//
+// Returns: *this.
+//
+// Remarks: The exception specification is equivalent to:
+// is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&
+// is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotMoveConstructible {
+  NotMoveConstructible(NotMoveConstructible&&)            = delete;
+  NotMoveConstructible& operator=(NotMoveConstructible&&) = default;
+};
+
+struct NotMoveAssignable {
+  NotMoveAssignable(NotMoveAssignable&&)            = default;
+  NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
+};
+
+struct MoveCtorMayThrow {
+  MoveCtorMayThrow(MoveCtorMayThrow&&) noexcept(false) {}
+  MoveCtorMayThrow& operator=(MoveCtorMayThrow&&) noexcept = default;
+};
+
+// Test constraints
+static_assert(std::is_move_assignable_v<std::expected<int, int>>);
+
+// !is_move_assignable_v<T>
+static_assert(!std::is_move_assignable_v<std::expected<NotMoveAssignable, int>>);
+
+// !is_move_constructible_v<T>
+static_assert(!std::is_move_assignable_v<std::expected<NotMoveConstructible, int>>);
+
+// !is_move_assignable_v<E>
+static_assert(!std::is_move_assignable_v<std::expected<int, NotMoveAssignable>>);
+
+// !is_move_constructible_v<E>
+static_assert(!std::is_move_assignable_v<std::expected<int, NotMoveConstructible>>);
+
+// !is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>
+static_assert(std::is_move_assignable_v<std::expected<MoveCtorMayThrow, int>>);
+
+// is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(std::is_move_assignable_v<std::expected<int, MoveCtorMayThrow>>);
+
+// !is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_move_assignable_v<std::expected<MoveCtorMayThrow, MoveCtorMayThrow>>);
+
+struct MoveAssignMayThrow {
+  MoveAssignMayThrow(MoveAssignMayThrow&&) noexcept = default;
+  MoveAssignMayThrow& operator=(MoveAssignMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test noexcept
+static_assert(std::is_nothrow_move_assignable_v<std::expected<int, int>>);
+
+// !is_nothrow_move_assignable_v<T>
+static_assert(!std::is_nothrow_move_assignable_v<std::expected<MoveAssignMayThrow, int>>);
+
+// !is_nothrow_move_constructible_v<T>
+static_assert(!std::is_nothrow_move_assignable_v<std::expected<MoveCtorMayThrow, int>>);
+
+// !is_nothrow_move_assignable_v<E>
+static_assert(!std::is_nothrow_move_assignable_v<std::expected<int, MoveAssignMayThrow>>);
+
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_nothrow_move_assignable_v<std::expected<int, MoveCtorMayThrow>>);
+
+constexpr bool test() {
+  // If this->has_value() && rhs.has_value() is true, equivalent to val = std::move(*rhs).
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<Traced, int> e1(std::in_place, oldState, 5);
+    std::expected<Traced, int> e2(std::in_place, newState, 10);
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<Traced, int>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+    assert(oldState.moveAssignCalled);
+  }
+
+  // - Otherwise, if this->has_value() is true, equivalent to:
+  // reinit-expected(unex, val, rhs.error())
+  //  E move is not noexcept
+  //  In this case, it should call the branch
+  //
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  //
+  {
+    TracedNoexcept::state oldState{};
+    Traced::state newState{};
+    std::expected<TracedNoexcept, Traced> e1(std::in_place, oldState, 5);
+    std::expected<TracedNoexcept, Traced> e2(std::unexpect, newState, 10);
+
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<TracedNoexcept, Traced>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+
+    assert(!oldState.moveAssignCalled);
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(!newState.copyCtorCalled);
+    assert(newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // - Otherwise, if this->has_value() is true, equivalent to:
+  // reinit-expected(unex, val, rhs.error())
+  //  E move is noexcept
+  //  In this case, it should call the branch
+  //
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::forward<Args>(args)...);
+  //
+  {
+    Traced::state oldState{};
+    TracedNoexcept::state newState{};
+    std::expected<Traced, TracedNoexcept> e1(std::in_place, oldState, 5);
+    std::expected<Traced, TracedNoexcept> e2(std::unexpect, newState, 10);
+
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<Traced, TracedNoexcept>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(!newState.copyCtorCalled);
+    assert(newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // - Otherwise, if rhs.has_value() is true, equivalent to:
+  // reinit-expected(val, unex, *rhs)
+  //  T move is not noexcept
+  //  In this case, it should call the branch
+  //
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  //
+  {
+    TracedNoexcept::state oldState{};
+    Traced::state newState{};
+    std::expected<Traced, TracedNoexcept> e1(std::unexpect, oldState, 5);
+    std::expected<Traced, TracedNoexcept> e2(std::in_place, newState, 10);
+
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<Traced, TracedNoexcept>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(!newState.copyCtorCalled);
+    assert(newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // - Otherwise, if rhs.has_value() is true, equivalent to:
+  // reinit-expected(val, unex, *rhs)
+  //  T move is noexcept
+  //  In this case, it should call the branch
+  //
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::forward<Args>(args)...);
+  //
+  {
+    Traced::state oldState{};
+    TracedNoexcept::state newState{};
+    std::expected<TracedNoexcept, Traced> e1(std::unexpect, oldState, 5);
+    std::expected<TracedNoexcept, Traced> e2(std::in_place, newState, 10);
+
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<TracedNoexcept, Traced>&>);
+    assert(&x == &e1);
+
+    assert(e1.has_value());
+    assert(e1.value().data_ == 10);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!oldState.copyCtorCalled);
+    assert(!newState.copyCtorCalled);
+    assert(newState.moveCtorCalled);
+    assert(!newState.dtorCalled);
+  }
+
+  // Otherwise, equivalent to unex = rhs.error().
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<int, Traced> e1(std::unexpect, oldState, 5);
+    std::expected<int, Traced> e2(std::unexpect, newState, 10);
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<int, Traced>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(oldState.moveAssignCalled);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  // assign value throw on move
+  {
+    std::expected<ThrowOnMoveConstruct, int> e1(std::unexpect, 5);
+    std::expected<ThrowOnMoveConstruct, int> e2(std::in_place);
+    try {
+      e1 = std::move(e2);
+      assert(false);
+    } catch (Except) {
+      assert(!e1.has_value());
+      assert(e1.error() == 5);
+    }
+  }
+
+  // assign error throw on move
+  {
+    std::expected<int, ThrowOnMoveConstruct> e1(5);
+    std::expected<int, ThrowOnMoveConstruct> e2(std::unexpect);
+    try {
+      e1 = std::move(e2);
+      assert(false);
+    } catch (Except) {
+      assert(e1.has_value());
+      assert(*e1 == 5);
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.copy.pass.cpp
new file mode 100644
index 0000000000000..a45dd45cc963c
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.copy.pass.cpp
@@ -0,0 +1,200 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class G>
+//   constexpr expected& operator=(const unexpected<G>& e);
+//
+// Let GF be const G&
+// Constraints:
+// - is_constructible_v<E, GF> is true; and
+// - is_assignable_v<E&, GF> is true; and
+// - is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
+//   is_nothrow_move_constructible_v<E> is true.
+//
+// Effects:
+// - If has_value() is true, equivalent to:
+//   reinit-expected(unex, val, std::forward<GF>(e.error()));
+//   has_val = false;
+// - Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+// Returns: *this.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotCopyConstructible {
+  NotCopyConstructible(const NotCopyConstructible&)            = delete;
+  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow const&)            = default;
+  MoveMayThrow& operator=(const MoveMayThrow&) = default;
+  MoveMayThrow(MoveMayThrow&&) noexcept(false) {}
+  MoveMayThrow& operator=(MoveMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test constraints
+static_assert(std::is_assignable_v<std::expected<int, int>&, const std::unexpected<int>&>);
+
+// !is_constructible_v<E, GF>
+static_assert(
+    !std::is_assignable_v<std::expected<int, NotCopyConstructible>&, const std::unexpected<NotCopyConstructible>&>);
+
+// !is_assignable_v<E&, GF>
+static_assert(!std::is_assignable_v<std::expected<int, NotCopyAssignable>&, const std::unexpected<NotCopyAssignable>&>);
+
+template <bool moveNoexcept, bool convertNoexcept>
+struct MaybeNoexcept {
+  explicit MaybeNoexcept(int) noexcept(convertNoexcept);
+  MaybeNoexcept(MaybeNoexcept&&) noexcept(moveNoexcept);
+  MaybeNoexcept& operator=(MaybeNoexcept&&) = default;
+  MaybeNoexcept& operator=(int);
+};
+
+// !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<true, false>>&,
+                                   const std::unexpected<int>&>);
+
+// is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, true>>&,
+                                   const std::unexpected<int>&>);
+
+// !is_nothrow_constructible_v<E, GF> && is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<true, true>, MaybeNoexcept<false, false>>&,
+                                   const std::unexpected<int>&>);
+
+// !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, false>>&,
+                                    const std::unexpected<int>&>);
+
+constexpr bool test() {
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // is_nothrow_constructible_v<E, GF>
+  //
+  //  In this case, it should call the branch
+  //    destroy_at(addressof(oldval));
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, BothNoexcept> e(std::in_place, oldState, 5);
+    const std::unexpected<int> un(10);
+    decltype(auto) x = (e = un);
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, BothNoexcept>&>);
+    assert(&x == &e);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e.error().copiedFromInt);
+  }
+
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // !is_nothrow_constructible_v<E, GF> && is_nothrow_move_constructible_v<E>
+  //
+  //  In this case, it should call the branch
+  //  T tmp(std::forward<Args>(args)...);
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::move(tmp));
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, MoveNoexceptConvThrow> e(std::in_place, oldState, 5);
+    const std::unexpected<int> un(10);
+    decltype(auto) x = (e = un);
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, MoveNoexceptConvThrow>&>);
+    assert(&x == &e);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!e.error().copiedFromInt);
+    assert(e.error().movedFromTmp);
+  }
+
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<E>
+  // is_nothrow_move_constructible_v<T>
+  //
+  //  In this case, it should call the branch
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, BothMayThrow> e(std::in_place, oldState, 5);
+    const std::unexpected<int> un(10);
+    decltype(auto) x = (e = un);
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, BothMayThrow>&>);
+    assert(&x == &e);
+
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e.error().copiedFromInt);
+  }
+
+  // Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<int, Traced> e1(std::unexpect, oldState, 5);
+    const std::unexpected<Traced> e(std::in_place, newState, 10);
+    decltype(auto) x = (e1 = e);
+    static_assert(std::same_as<decltype(x), std::expected<int, Traced>&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(oldState.copyAssignCalled);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<int, ThrowOnConvert> e1(std::in_place, 5);
+  const std::unexpected<int> un(10);
+  try {
+    e1 = un;
+    assert(false);
+  } catch (Except) {
+    assert(e1.has_value());
+    assert(*e1 == 5);
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.move.pass.cpp
new file mode 100644
index 0000000000000..cb56d30174d1a
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/assign.unexpected.move.pass.cpp
@@ -0,0 +1,200 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class G>
+//   constexpr expected& operator=(unexpected<G>&& e);
+//
+// Let GF be G
+// Constraints:
+// - is_constructible_v<E, GF> is true; and
+// - is_assignable_v<E&, GF> is true; and
+// - is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
+//   is_nothrow_move_constructible_v<E> is true.
+//
+// Effects:
+// - If has_value() is true, equivalent to:
+//   reinit-expected(unex, val, std::forward<GF>(e.error()));
+//   has_val = false;
+// - Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+// Returns: *this.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotMoveConstructible {
+  NotMoveConstructible(NotMoveConstructible&&)            = delete;
+  NotMoveConstructible& operator=(NotMoveConstructible&&) = default;
+};
+
+struct NotMoveAssignable {
+  NotMoveAssignable(NotMoveAssignable&&)            = default;
+  NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow const&)            = default;
+  MoveMayThrow& operator=(const MoveMayThrow&) = default;
+  MoveMayThrow(MoveMayThrow&&) noexcept(false) {}
+  MoveMayThrow& operator=(MoveMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test constraints
+static_assert(std::is_assignable_v<std::expected<int, int>&, std::unexpected<int>&&>);
+
+// !is_constructible_v<E, GF>
+static_assert(
+    !std::is_assignable_v<std::expected<int, NotMoveConstructible>&, std::unexpected<NotMoveConstructible>&&>);
+
+// !is_assignable_v<E&, GF>
+static_assert(!std::is_assignable_v<std::expected<int, NotMoveAssignable>&, std::unexpected<NotMoveAssignable>&&>);
+
+template <bool moveNoexcept, bool convertNoexcept>
+struct MaybeNoexcept {
+  explicit MaybeNoexcept(int) noexcept(convertNoexcept);
+  MaybeNoexcept(MaybeNoexcept&&) noexcept(moveNoexcept);
+  MaybeNoexcept& operator=(MaybeNoexcept&&) = default;
+  MaybeNoexcept& operator=(int);
+};
+
+// !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<true, false>>&,
+                                   std::unexpected<int>&&>);
+
+// is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, true>>&,
+                                   std::unexpected<int>&&>);
+
+// !is_nothrow_constructible_v<E, GF> && is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<true, true>, MaybeNoexcept<false, false>>&,
+                                   std::unexpected<int>&&>);
+
+// !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, false>>&,
+                                    std::unexpected<int>&&>);
+
+constexpr bool test() {
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // is_nothrow_constructible_v<E, GF>
+  //
+  //  In this case, it should call the branch
+  //    destroy_at(addressof(oldval));
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, BothNoexcept> e(std::in_place, oldState, 5);
+    std::unexpected<int> un(10);
+    decltype(auto) x = (e = std::move(un));
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, BothNoexcept>&>);
+    assert(&x == &e);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e.error().movedFromInt);
+  }
+
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // !is_nothrow_constructible_v<E, GF> && is_nothrow_move_constructible_v<E>
+  //
+  //  In this case, it should call the branch
+  //  T tmp(std::forward<Args>(args)...);
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::move(tmp));
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, MoveNoexceptConvThrow> e(std::in_place, oldState, 5);
+    std::unexpected<int> un(10);
+    decltype(auto) x = (e = std::move(un));
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, MoveNoexceptConvThrow>&>);
+    assert(&x == &e);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!e.error().movedFromInt);
+    assert(e.error().movedFromTmp);
+  }
+
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<E>
+  // is_nothrow_move_constructible_v<T>
+  //
+  //  In this case, it should call the branch
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, BothMayThrow> e(std::in_place, oldState, 5);
+    std::unexpected<int> un(10);
+    decltype(auto) x = (e = std::move(un));
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, BothMayThrow>&>);
+    assert(&x == &e);
+
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e.error().movedFromInt);
+  }
+
+  // Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<int, Traced> e1(std::unexpect, oldState, 5);
+    std::unexpected<Traced> e(std::in_place, newState, 10);
+    decltype(auto) x = (e1 = std::move(e));
+    static_assert(std::same_as<decltype(x), std::expected<int, Traced >&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(oldState.moveAssignCalled);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<int, ThrowOnConvert> e1(std::in_place, 5);
+  std::unexpected<int> un(10);
+  try {
+    e1 = std::move(un);
+    assert(false);
+  } catch (Except) {
+    assert(e1.has_value());
+    assert(*e1 == 5);
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.intializer_list.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.intializer_list.pass.cpp
new file mode 100644
index 0000000000000..3cdfcde3f4d69
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.intializer_list.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class U, class... Args>
+//   constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept;
+// Constraints: is_nothrow_constructible_v<T, initializer_list<U>&, Args...> is true.
+//
+// Effects: Equivalent to:
+// if (has_value()) {
+//   destroy_at(addressof(val));
+// } else {
+//   destroy_at(addressof(unex));
+//   has_val = true;
+// }
+// return *construct_at(addressof(val), il, std::forward<Args>(args)...);
+
+#include <algorithm>
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+template <class T, class... Args>
+concept CanEmplace = requires(T t, Args&&... args) { t.emplace(std::forward<Args>(args)...); };
+
+static_assert(CanEmplace<std::expected<int, int>, int>);
+
+template <bool Noexcept>
+struct CtorFromInitalizerList {
+  CtorFromInitalizerList(std::initializer_list<int>&) noexcept(Noexcept);
+  CtorFromInitalizerList(std::initializer_list<int>&, int) noexcept(Noexcept);
+};
+
+static_assert(CanEmplace<std::expected<CtorFromInitalizerList<true>, int>, std::initializer_list<int>&>);
+static_assert(!CanEmplace<std::expected<CtorFromInitalizerList<false>, int>, std::initializer_list<int>&>);
+static_assert(CanEmplace<std::expected<CtorFromInitalizerList<true>, int>, std::initializer_list<int>&, int>);
+static_assert(!CanEmplace<std::expected<CtorFromInitalizerList<false>, int>, std::initializer_list<int>&, int>);
+
+struct Data {
+  std::initializer_list<int> il;
+  int i;
+
+  constexpr Data(std::initializer_list<int>& l, int ii) noexcept : il(l), i(ii) {}
+};
+
+constexpr bool test() {
+  // has_value
+  {
+    auto list1 = {1, 2, 3};
+    auto list2 = {4, 5, 6};
+    std::expected<Data, int> e(std::in_place, list1, 5);
+    decltype(auto) x = e.emplace(list2, 10);
+    static_assert(std::same_as<decltype(x), Data&>);
+    assert(&x == &(*e));
+
+    assert(e.has_value());
+    assert(std::ranges::equal(e.value().il, list2));
+    assert(e.value().i == 10);
+  }
+
+  // !has_value
+  {
+    auto list = {4, 5, 6};
+    std::expected<Data, int> e(std::unexpect, 5);
+    decltype(auto) x = e.emplace(list, 10);
+    static_assert(std::same_as<decltype(x), Data&>);
+    assert(&x == &(*e));
+
+    assert(e.has_value());
+    assert(std::ranges::equal(e.value().il, list));
+    assert(e.value().i == 10);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.pass.cpp
new file mode 100644
index 0000000000000..66c066db3c59f
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class... Args>
+//   constexpr T& emplace(Args&&... args) noexcept;
+// Constraints: is_nothrow_constructible_v<T, Args...> is true.
+//
+// Effects: Equivalent to:
+// if (has_value()) {
+//   destroy_at(addressof(val));
+// } else {
+//   destroy_at(addressof(unex));
+//   has_val = true;
+// }
+// return *construct_at(addressof(val), std::forward<Args>(args)...);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+template <class T, class... Args>
+concept CanEmplace = requires(T t, Args&&... args) { t.emplace(std::forward<Args>(args)...); };
+
+static_assert(CanEmplace<std::expected<int, int>, int>);
+
+template <bool Noexcept>
+struct CtorFromInt {
+  CtorFromInt(int) noexcept(Noexcept);
+  CtorFromInt(int, int) noexcept(Noexcept);
+};
+
+static_assert(CanEmplace<std::expected<CtorFromInt<true>, int>, int>);
+static_assert(CanEmplace<std::expected<CtorFromInt<true>, int>, int, int>);
+static_assert(!CanEmplace<std::expected<CtorFromInt<false>, int>, int>);
+static_assert(!CanEmplace<std::expected<CtorFromInt<false>, int>, int, int>);
+
+constexpr bool test() {
+  // has_value
+  {
+    BothNoexcept::state oldState{};
+    BothNoexcept::state newState{};
+    std::expected<BothNoexcept, int> e(std::in_place, oldState, 5);
+    decltype(auto) x = e.emplace(newState, 10);
+    static_assert(std::same_as<decltype(x), BothNoexcept&>);
+    assert(&x == &(*e));
+
+    assert(oldState.dtorCalled);
+    assert(e.has_value());
+    assert(e.value().data_ == 10);
+  }
+
+  // !has_value
+  {
+    BothMayThrow::state oldState{};
+    std::expected<int, BothMayThrow> e(std::unexpect, oldState, 5);
+    decltype(auto) x = e.emplace(10);
+    static_assert(std::same_as<decltype(x), int&>);
+    assert(&x == &(*e));
+
+    assert(oldState.dtorCalled);
+    assert(e.has_value());
+    assert(e.value() == 10);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.copy.pass.cpp
new file mode 100644
index 0000000000000..9274b9a2c030e
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.copy.pass.cpp
@@ -0,0 +1,203 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+//  template<class U, class G>
+//    constexpr explicit(see below) expected(const expected<U, G>&);
+//
+// Let:
+// - UF be const U&
+// - GF be const G&
+//
+// Constraints:
+// - is_constructible_v<T, UF> is true; and
+// - is_constructible_v<E, GF> is true; and
+// - is_constructible_v<T, expected<U, G>&> is false; and
+// - is_constructible_v<T, expected<U, G>> is false; and
+// - is_constructible_v<T, const expected<U, G>&> is false; and
+// - is_constructible_v<T, const expected<U, G>> is false; and
+// - is_convertible_v<expected<U, G>&, T> is false; and
+// - is_convertible_v<expected<U, G>&&, T> is false; and
+// - is_convertible_v<const expected<U, G>&, T> is false; and
+// - is_convertible_v<const expected<U, G>&&, T> is false; and
+// - is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, expected<U, G>> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>> is false.
+//
+// Effects: If rhs.has_value(), direct-non-list-initializes val with std::forward<UF>(*rhs). Otherwise, direct-non-list-initializes unex with std::forward<GF>(rhs.error()).
+//
+// Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val or unex.
+//
+// Remarks: The expression inside explicit is equivalent to !is_convertible_v<UF, T> || !is_convertible_v<GF, E>.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test Constraints:
+template <class T1, class Err1, class T2, class Err2>
+concept canCstrFromExpected = std::is_constructible_v<std::expected<T1, Err1>, const std::expected<T2, Err2>&>;
+
+struct CtorFromInt {
+  CtorFromInt(int);
+};
+
+static_assert(canCstrFromExpected<CtorFromInt, int, int, int>);
+
+struct NoCtorFromInt {};
+
+// !is_constructible_v<T, UF>
+static_assert(!canCstrFromExpected<NoCtorFromInt, int, int, int>);
+
+// !is_constructible_v<E, GF>
+static_assert(!canCstrFromExpected<int, NoCtorFromInt, int, int>);
+
+template <class T>
+struct CtorFrom {
+  explicit CtorFrom(int)
+    requires(!std::same_as<T, int>);
+  explicit CtorFrom(T);
+  explicit CtorFrom(auto&&) = delete;
+};
+
+// is_constructible_v<T, expected<U, G>&>
+static_assert(!canCstrFromExpected<CtorFrom<std::expected<int, int>&>, int, int, int>);
+
+// is_constructible_v<T, expected<U, G>>
+static_assert(!canCstrFromExpected<CtorFrom<std::expected<int, int>&&>, int, int, int>);
+
+// is_constructible_v<T, expected<U, G>&>
+// note that this is true because it is covered by the other overload
+//   template<class U = T> constexpr explicit(see below) expected(U&& v);
+// The fact that it is not ambiguous proves that the overload under testing is removed
+static_assert(canCstrFromExpected<CtorFrom<std::expected<int, int> const&>, int, int, int>);
+
+// is_constructible_v<T, expected<U, G>>
+static_assert(!canCstrFromExpected<CtorFrom<std::expected<int, int> const&&>, int, int, int>);
+
+template <class T>
+struct ConvertFrom {
+  ConvertFrom(int)
+    requires(!std::same_as<T, int>);
+  ConvertFrom(T);
+  ConvertFrom(auto&&) = delete;
+};
+
+// is_convertible_v<expected<U, G>&, T>
+static_assert(!canCstrFromExpected<ConvertFrom<std::expected<int, int>&>, int, int, int>);
+
+// is_convertible_v<expected<U, G>&&, T>
+static_assert(!canCstrFromExpected<ConvertFrom<std::expected<int, int>&&>, int, int, int>);
+
+// is_convertible_v<const expected<U, G>&, T>
+// note that this is true because it is covered by the other overload
+//   template<class U = T> constexpr explicit(see below) expected(U&& v);
+// The fact that it is not ambiguous proves that the overload under testing is removed
+static_assert(canCstrFromExpected<ConvertFrom<std::expected<int, int> const&>, int, int, int>);
+
+// is_convertible_v<const expected<U, G>&&, T>
+static_assert(!canCstrFromExpected<ConvertFrom<std::expected<int, int> const&&>, int, int, int>);
+
+// Note for below 4 tests, because their E is constructible from cvref of std::expected<int, int>,
+// unexpected<E> will be constructible from cvref of std::expected<int, int>
+// is_constructible_v<unexpected<E>, expected<U, G>&>
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int>&>, int, int>);
+
+// is_constructible_v<unexpected<E>, expected<U, G>>
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int>&&>, int, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>&> is false
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int> const&>, int, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>>
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int> const&&>, int, int>);
+
+// test explicit
+static_assert(std::is_convertible_v<const std::expected<int, int>&, std::expected<short, long>>);
+
+// !is_convertible_v<UF, T>
+static_assert(std::is_constructible_v<std::expected<CtorFrom<int>, int>, const std::expected<int, int>&>);
+static_assert(!std::is_convertible_v<const std::expected<int, int>&, std::expected<CtorFrom<int>, int>>);
+
+// !is_convertible_v<GF, E>.
+static_assert(std::is_constructible_v<std::expected<int, CtorFrom<int>>, const std::expected<int, int>&>);
+static_assert(!std::is_convertible_v<const std::expected<int, int>&, std::expected<int, CtorFrom<int>>>);
+
+struct Data {
+  int i;
+  constexpr Data(int ii) : i(ii) {}
+};
+
+constexpr bool test() {
+  // convert the value
+  {
+    const std::expected<int, int> e1(5);
+    std::expected<Data, int> e2 = e1;
+    assert(e2.has_value());
+    assert(e2.value().i == 5);
+    assert(e1.has_value());
+    assert(e1.value() == 5);
+  }
+
+  // convert the error
+  {
+    const std::expected<int, int> e1(std::unexpect, 5);
+    std::expected<int, Data> e2 = e1;
+    assert(!e2.has_value());
+    assert(e2.error().i == 5);
+    assert(!e1.has_value());
+    assert(e1.error() == 5);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct ThrowingInt {
+    ThrowingInt(int) { throw Except{}; }
+  };
+
+  // throw on converting value
+  {
+    const std::expected<int, int> e1;
+    try {
+      [[maybe_unused]] std::expected<ThrowingInt, int> e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+  // throw on converting error
+  {
+    const std::expected<int, int> e1(std::unexpect);
+    try {
+      [[maybe_unused]] std::expected<int, ThrowingInt> e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.move.pass.cpp
new file mode 100644
index 0000000000000..71979311bfd10
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.convert.move.pass.cpp
@@ -0,0 +1,202 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+//  template<class U, class G>
+//    constexpr explicit(see below) expected(expected<U, G>&&);
+//
+// Let:
+// - UF be const U
+// - GF be const G
+//
+// Constraints:
+// - is_constructible_v<T, UF> is true; and
+// - is_constructible_v<E, GF> is true; and
+// - is_constructible_v<T, expected<U, G>&> is false; and
+// - is_constructible_v<T, expected<U, G>> is false; and
+// - is_constructible_v<T, const expected<U, G>&> is false; and
+// - is_constructible_v<T, const expected<U, G>> is false; and
+// - is_convertible_v<expected<U, G>&, T> is false; and
+// - is_convertible_v<expected<U, G>&&, T> is false; and
+// - is_convertible_v<const expected<U, G>&, T> is false; and
+// - is_convertible_v<const expected<U, G>&&, T> is false; and
+// - is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, expected<U, G>> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>> is false.
+//
+// Effects: If rhs.has_value(), direct-non-list-initializes val with std::forward<UF>(*rhs). Otherwise, direct-non-list-initializes unex with std::forward<GF>(rhs.error()).
+//
+// Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val or unex.
+//
+// Remarks: The expression inside explicit is equivalent to !is_convertible_v<UF, T> || !is_convertible_v<GF, E>.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+template <class T1, class Err1, class T2, class Err2>
+concept canCstrFromExpected = std::is_constructible_v<std::expected<T1, Err1>, std::expected<T2, Err2>&&>;
+
+struct CtorFromInt {
+  CtorFromInt(int);
+};
+
+static_assert(canCstrFromExpected<CtorFromInt, int, int, int>);
+
+struct NoCtorFromInt {};
+
+// !is_constructible_v<T, UF>
+static_assert(!canCstrFromExpected<NoCtorFromInt, int, int, int>);
+
+// !is_constructible_v<E, GF>
+static_assert(!canCstrFromExpected<int, NoCtorFromInt, int, int>);
+
+template <class T>
+struct CtorFrom {
+  explicit CtorFrom(int)
+    requires(!std::same_as<T, int>);
+  explicit CtorFrom(T);
+  explicit CtorFrom(auto&&) = delete;
+};
+
+// is_constructible_v<T, expected<U, G>&>
+static_assert(!canCstrFromExpected<CtorFrom<std::expected<int, int>&>, int, int, int>);
+
+// is_constructible_v<T, expected<U, G>>
+// note that this is true because it is covered by the other overload
+//   template<class U = T> constexpr explicit(see below) expected(U&& v);
+// The fact that it is not ambiguous proves that the overload under testing is removed
+static_assert(canCstrFromExpected<CtorFrom<std::expected<int, int>&&>, int, int, int>);
+
+// is_constructible_v<T, expected<U, G>&>
+static_assert(!canCstrFromExpected<CtorFrom<std::expected<int, int> const&>, int, int, int>);
+
+// is_constructible_v<T, expected<U, G>>
+static_assert(!canCstrFromExpected<CtorFrom<std::expected<int, int> const&&>, int, int, int>);
+
+template <class T>
+struct ConvertFrom {
+  ConvertFrom(int)
+    requires(!std::same_as<T, int>);
+  ConvertFrom(T);
+  ConvertFrom(auto&&) = delete;
+};
+
+// is_convertible_v<expected<U, G>&, T>
+static_assert(!canCstrFromExpected<ConvertFrom<std::expected<int, int>&>, int, int, int>);
+
+// is_convertible_v<expected<U, G>&&, T>
+// note that this is true because it is covered by the other overload
+//   template<class U = T> constexpr explicit(see below) expected(U&& v);
+// The fact that it is not ambiguous proves that the overload under testing is removed
+static_assert(canCstrFromExpected<ConvertFrom<std::expected<int, int>&&>, int, int, int>);
+
+// is_convertible_v<const expected<U, G>&, T>
+static_assert(!canCstrFromExpected<ConvertFrom<std::expected<int, int> const&>, int, int, int>);
+
+// is_convertible_v<const expected<U, G>&&, T>
+static_assert(!canCstrFromExpected<ConvertFrom<std::expected<int, int> const&&>, int, int, int>);
+
+// is_constructible_v<unexpected<E>, expected<U, G>&>
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int>&>, int, int>);
+
+// is_constructible_v<unexpected<E>, expected<U, G>>
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int>&&>, int, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>&> is false
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int> const&>, int, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>>
+static_assert(!canCstrFromExpected<int, CtorFrom<std::expected<int, int> const&&>, int, int>);
+
+// test explicit
+static_assert(std::is_convertible_v<std::expected<int, int>&&, std::expected<short, long>>);
+
+// !is_convertible_v<UF, T>
+static_assert(std::is_constructible_v<std::expected<CtorFrom<int>, int>, std::expected<int, int>&&>);
+static_assert(!std::is_convertible_v<std::expected<int, int>&&, std::expected<CtorFrom<int>, int>>);
+
+// !is_convertible_v<GF, E>.
+static_assert(std::is_constructible_v<std::expected<int, CtorFrom<int>>, std::expected<int, int>&&>);
+static_assert(!std::is_convertible_v<std::expected<int, int>&&, std::expected<int, CtorFrom<int>>>);
+
+struct Data {
+  MoveOnly data;
+  constexpr Data(MoveOnly&& m) : data(std::move(m)) {}
+};
+
+constexpr bool test() {
+  // convert the value
+  {
+    std::expected<MoveOnly, int> e1(5);
+    std::expected<Data, int> e2 = std::move(e1);
+    assert(e2.has_value());
+    assert(e2.value().data.get() == 5);
+    assert(e1.has_value());
+    assert(e1.value().get() == 0);
+  }
+
+  // convert the error
+  {
+    std::expected<int, MoveOnly> e1(std::unexpect, 5);
+    std::expected<int, Data> e2 = std::move(e1);
+    assert(!e2.has_value());
+    assert(e2.error().data.get() == 5);
+    assert(!e1.has_value());
+    assert(e1.error().get() == 0);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct ThrowingInt {
+    ThrowingInt(int) { throw Except{}; }
+  };
+
+  // throw on converting value
+  {
+    const std::expected<int, int> e1;
+    try {
+      [[maybe_unused]] std::expected<ThrowingInt, int> e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+  // throw on converting error
+  {
+    const std::expected<int, int> e1(std::unexpect);
+    try {
+      [[maybe_unused]] std::expected<int, ThrowingInt> e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

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
new file mode 100644
index 0000000000000..0b3451e3f192d
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr expected(const expected& rhs);
+//
+// Effects: If rhs.has_value() is true, direct-non-list-initializes val with *rhs.
+// Otherwise, direct-non-list-initializes unex with rhs.error().
+//
+// Postconditions: rhs.has_value() == this->has_value().
+//
+// Throws: Any exception thrown by the initialization of val or unex.
+//
+// Remarks: This constructor is defined as deleted unless
+// - is_copy_constructible_v<T> is true and
+// - is_copy_constructible_v<E> is true.
+//
+// This constructor is trivial if
+// - is_trivially_copy_constructible_v<T> is true and
+// - is_trivially_copy_constructible_v<E> is true.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct NonCopyable {
+  NonCopyable(const NonCopyable&) = delete;
+};
+
+struct CopyableNonTrivial {
+  int i;
+  constexpr CopyableNonTrivial(int ii) : i(ii) {}
+  constexpr CopyableNonTrivial(const CopyableNonTrivial& o) { i = o.i; }
+  friend constexpr bool operator==(const CopyableNonTrivial&, const CopyableNonTrivial&) = default;
+};
+
+// Test: This constructor is defined as deleted unless
+// - is_copy_constructible_v<T> is true and
+// - is_copy_constructible_v<E> is true.
+static_assert(std::is_copy_constructible_v<std::expected<int, int>>);
+static_assert(std::is_copy_constructible_v<std::expected<CopyableNonTrivial, int>>);
+static_assert(std::is_copy_constructible_v<std::expected<int, CopyableNonTrivial>>);
+static_assert(std::is_copy_constructible_v<std::expected<CopyableNonTrivial, CopyableNonTrivial>>);
+static_assert(!std::is_copy_constructible_v<std::expected<NonCopyable, int>>);
+static_assert(!std::is_copy_constructible_v<std::expected<int, NonCopyable>>);
+static_assert(!std::is_copy_constructible_v<std::expected<NonCopyable, NonCopyable>>);
+
+// Test: This constructor is trivial if
+// - is_trivially_copy_constructible_v<T> is true and
+// - is_trivially_copy_constructible_v<E> is true.
+#if __cpp_concepts >= 202002
+static_assert(std::is_trivially_copy_constructible_v<std::expected<int, int>>);
+#endif
+static_assert(!std::is_trivially_copy_constructible_v<std::expected<CopyableNonTrivial, int>>);
+static_assert(!std::is_trivially_copy_constructible_v<std::expected<int, CopyableNonTrivial>>);
+static_assert(!std::is_trivially_copy_constructible_v<std::expected<CopyableNonTrivial, CopyableNonTrivial>>);
+
+constexpr bool test() {
+  // copy the value non-trivial
+  {
+    const std::expected<CopyableNonTrivial, int> e1(5);
+    auto e2 = e1;
+    assert(e2.has_value());
+    assert(e2.value().i == 5);
+  }
+
+  // copy the error non-trivial
+  {
+    const std::expected<int, CopyableNonTrivial> e1(std::unexpect, 5);
+    auto e2 = e1;
+    assert(!e2.has_value());
+    assert(e2.error().i == 5);
+  }
+
+  // copy the value trivial
+  {
+    const std::expected<int, int> e1(5);
+    auto e2 = e1;
+    assert(e2.has_value());
+    assert(e2.value() == 5);
+  }
+
+  // copy the error trivial
+  {
+    const std::expected<int, int> e1(std::unexpect, 5);
+    auto e2 = e1;
+    assert(!e2.has_value());
+    assert(e2.error() == 5);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing() = default;
+    Throwing(const Throwing&) { throw Except{}; }
+  };
+
+  // throw on copying value
+  {
+    const std::expected<Throwing, int> e1;
+    try {
+      [[maybe_unused]] auto e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+  // throw on copying error
+  {
+    const std::expected<int, Throwing> e1(std::unexpect);
+    try {
+      [[maybe_unused]] auto e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.default.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.default.pass.cpp
new file mode 100644
index 0000000000000..431e604e8b692
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.default.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+//
+// constexpr expected();
+
+// Constraints: is_default_constructible_v<T> is true.
+//
+// Effects: Value-initializes val.
+// Postconditions: has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct NoDedefaultCtor {
+  NoDedefaultCtor() = delete;
+};
+
+// Test constraints
+static_assert(std::is_default_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_default_constructible_v<std::expected<NoDedefaultCtor, int>>);
+
+struct MyInt {
+  int i;
+  friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
+};
+
+template <class T, class E>
+constexpr void testDefaultCtor() {
+  std::expected<T, E> e;
+  assert(e.has_value());
+  assert(e.value() == T());
+}
+
+template <class T>
+constexpr void testTypes() {
+  testDefaultCtor<T, int>();
+  testDefaultCtor<T, NoDedefaultCtor>();
+}
+
+constexpr bool test() {
+  testTypes<int>();
+  testTypes<MyInt>();
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing() { throw Except{}; };
+  };
+
+  try {
+    std::expected<Throwing, int> u;
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace.pass.cpp
new file mode 100644
index 0000000000000..9a033eaeb7d6a
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class... Args>
+//   constexpr explicit expected(in_place_t, Args&&... args);
+//
+// Constraints: is_constructible_v<T, Args...> is true.
+//
+// Effects: Direct-non-list-initializes val with std::forward<Args>(args)....
+//
+// Postconditions: has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <tuple>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(std::is_constructible_v<std::expected<int, int>, std::in_place_t>);
+static_assert(std::is_constructible_v<std::expected<int, int>, std::in_place_t, int>);
+
+// !is_constructible_v<T, Args...>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<foo, int>, std::in_place_t, int>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+static_assert(ImplicitlyConstructible<int, int>);
+
+static_assert(!ImplicitlyConstructible<std::expected<int, int>, std::in_place_t>);
+static_assert(!ImplicitlyConstructible<std::expected<int, int>, std::in_place_t, int>);
+
+struct CopyOnly {
+  int i;
+  constexpr CopyOnly(int ii) : i(ii) {}
+  CopyOnly(const CopyOnly&) = default;
+  CopyOnly(CopyOnly&&)      = delete;
+  friend constexpr bool operator==(const CopyOnly& mi, int ii) { return mi.i == ii; }
+};
+
+template <class T>
+constexpr void testInt() {
+  std::expected<T, int> e(std::in_place, 5);
+  assert(e.has_value());
+  assert(e.value() == 5);
+}
+
+template <class T>
+constexpr void testLValue() {
+  T t(5);
+  std::expected<T, int> e(std::in_place, t);
+  assert(e.has_value());
+  assert(e.value() == 5);
+}
+
+template <class T>
+constexpr void testRValue() {
+  std::expected<T, int> e(std::in_place, T(5));
+  assert(e.has_value());
+  assert(e.value() == 5);
+}
+
+constexpr bool test() {
+  testInt<int>();
+  testInt<CopyOnly>();
+  testInt<MoveOnly>();
+  testLValue<int>();
+  testLValue<CopyOnly>();
+  testRValue<int>();
+  testRValue<MoveOnly>();
+
+  // no arg
+  {
+    std::expected<int, int> e(std::in_place);
+    assert(e.has_value());
+    assert(e.value() == 0);
+  }
+
+  // one arg
+  {
+    std::expected<int, int> e(std::in_place, 5);
+    assert(e.has_value());
+    assert(e.value() == 5);
+  }
+
+  // multi args
+  {
+    std::expected<std::tuple<int, short, MoveOnly>, int> e(std::in_place, 1, 2, MoveOnly(3));
+    assert(e.has_value());
+    assert((e.value() == std::tuple<int, short, MoveOnly>(1, 2, MoveOnly(3))));
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<Throwing, int> u(std::in_place, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace_init_list.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace_init_list.pass.cpp
new file mode 100644
index 0000000000000..3e85f87b25095
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.inplace_init_list.pass.cpp
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class U, class... Args>
+//   constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
+//
+// Constraints: is_constructible_v<T, initializer_list<U>&, Args...> is true.
+//
+// Effects: Direct-non-list-initializes val with il, std::forward<Args>(args)....
+//
+// Postconditions: has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val.
+
+#include <algorithm>
+#include <cassert>
+#include <expected>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(
+    std::is_constructible_v<std::expected<std::vector<int>, int>, std::in_place_t, std::initializer_list<int>>);
+
+// !is_constructible_v<T, initializer_list<U>&, Args...>
+static_assert(!std::is_constructible_v<std::expected<int, int>, std::in_place_t, std::initializer_list<int>>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+static_assert(ImplicitlyConstructible<int, int>);
+
+static_assert(
+    !ImplicitlyConstructible<std::expected<std::vector<int>, int>, std::in_place_t, std::initializer_list<int>>);
+
+template <class... Ts>
+struct Data {
+  std::vector<int> vec_;
+  std::tuple<Ts...> tuple_;
+
+  template <class... Us>
+    requires std::is_constructible_v<std::tuple<Ts...>, Us&&...>
+  constexpr Data(std::initializer_list<int> il, Us&&... us) : vec_(il), tuple_(std::forward<Us>(us)...) {}
+};
+
+constexpr bool test() {
+  // no arg
+  {
+    std::expected<Data<>, int> e(std::in_place, {1, 2, 3});
+    assert(e.has_value());
+    auto expectedList = {1, 2, 3};
+    assert(std::ranges::equal(e.value().vec_, expectedList));
+  }
+
+  // one arg
+  {
+    std::expected<Data<MoveOnly>, int> e(std::in_place, {4, 5, 6}, MoveOnly(5));
+    assert(e.has_value());
+    auto expectedList = {4, 5, 6};
+    assert((std::ranges::equal(e.value().vec_, expectedList)));
+    assert(std::get<0>(e.value().tuple_) == 5);
+  }
+
+  // multi args
+  {
+    int i = 5;
+    int j = 6;
+    MoveOnly m(7);
+    std::expected<Data<int&, int&&, MoveOnly>, int> e(std::in_place, {1, 2}, i, std::move(j), std::move(m));
+    assert(e.has_value());
+    auto expectedList = {1, 2};
+    assert((std::ranges::equal(e.value().vec_, expectedList)));
+    assert(&std::get<0>(e.value().tuple_) == &i);
+    assert(&std::get<1>(e.value().tuple_) == &j);
+    assert(std::get<2>(e.value().tuple_) == 7);
+    assert(m.get() == 0);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(std::initializer_list<int>, int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<Throwing, int> u(std::in_place, {1, 2}, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.move.pass.cpp
new file mode 100644
index 0000000000000..4ee5edd07a484
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.move.pass.cpp
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr expected(expected&& rhs) noexcept(see below);
+//
+// Constraints:
+// - is_move_constructible_v<T> is true and
+// - is_move_constructible_v<E> is true.
+//
+// Effects: If rhs.has_value() is true, direct-non-list-initializes val with std::move(*rhs).
+// Otherwise, direct-non-list-initializes unex with std::move(rhs.error()).
+//
+// Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val or unex.
+//
+// Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>.
+//
+// This constructor is trivial if
+// - is_trivially_move_constructible_v<T> is true and
+// - is_trivially_move_constructible_v<E> is true.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct NonMovable {
+  NonMovable(NonMovable&&) = delete;
+};
+
+struct MovableNonTrivial {
+  int i;
+  constexpr MovableNonTrivial(int ii) : i(ii) {}
+  constexpr MovableNonTrivial(MovableNonTrivial&& o) : i(o.i) { o.i = 0; }
+  friend constexpr bool operator==(const MovableNonTrivial&, const MovableNonTrivial&) = default;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow&&) {}
+};
+
+// Test Constraints:
+// - is_move_constructible_v<T> is true and
+// - is_move_constructible_v<E> is true.
+static_assert(std::is_move_constructible_v<std::expected<int, int>>);
+static_assert(std::is_move_constructible_v<std::expected<MovableNonTrivial, int>>);
+static_assert(std::is_move_constructible_v<std::expected<int, MovableNonTrivial>>);
+static_assert(std::is_move_constructible_v<std::expected<MovableNonTrivial, MovableNonTrivial>>);
+static_assert(!std::is_move_constructible_v<std::expected<NonMovable, int>>);
+static_assert(!std::is_move_constructible_v<std::expected<int, NonMovable>>);
+static_assert(!std::is_move_constructible_v<std::expected<NonMovable, NonMovable>>);
+
+// Test: This constructor is trivial if
+// - is_trivially_move_constructible_v<T> is true and
+// - is_trivially_move_constructible_v<E> is true.
+#if __cpp_concepts >= 202002
+static_assert(std::is_trivially_move_constructible_v<std::expected<int, int>>);
+#endif
+static_assert(!std::is_trivially_move_constructible_v<std::expected<MovableNonTrivial, int>>);
+static_assert(!std::is_trivially_move_constructible_v<std::expected<int, MovableNonTrivial>>);
+static_assert(!std::is_trivially_move_constructible_v<std::expected<MovableNonTrivial, MovableNonTrivial>>);
+
+// Test: The exception specification is equivalent to
+// is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>.
+static_assert(std::is_nothrow_move_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_move_constructible_v<std::expected<MoveMayThrow, int>>);
+static_assert(!std::is_nothrow_move_constructible_v<std::expected<int, MoveMayThrow>>);
+static_assert(!std::is_nothrow_move_constructible_v<std::expected<MoveMayThrow, MoveMayThrow>>);
+
+constexpr bool test() {
+  // move the value non-trivial
+  {
+    std::expected<MovableNonTrivial, int> e1(5);
+    auto e2 = std::move(e1);
+    assert(e2.has_value());
+    assert(e2.value().i == 5);
+    assert(e1.has_value());
+    assert(e1.value().i == 0);
+  }
+
+  // move the error non-trivial
+  {
+    std::expected<int, MovableNonTrivial> e1(std::unexpect, 5);
+    auto e2 = std::move(e1);
+    assert(!e2.has_value());
+    assert(e2.error().i == 5);
+    assert(!e1.has_value());
+    assert(e1.error().i == 0);
+  }
+
+  // move the value trivial
+  {
+    std::expected<int, int> e1(5);
+    auto e2 = std::move(e1);
+    assert(e2.has_value());
+    assert(e2.value() == 5);
+    assert(e1.has_value());
+  }
+
+  // move the error trivial
+  {
+    std::expected<int, int> e1(std::unexpect, 5);
+    auto e2 = std::move(e1);
+    assert(!e2.has_value());
+    assert(e2.error() == 5);
+    assert(!e1.has_value());
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing() = default;
+    Throwing(Throwing&&) { throw Except{}; }
+  };
+
+  // throw on moving value
+  {
+    std::expected<Throwing, int> e1;
+    try {
+      [[maybe_unused]] auto e2 = std::move(e1);
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+  // throw on moving error
+  {
+    std::expected<int, Throwing> e1(std::unexpect);
+    try {
+      [[maybe_unused]] auto e2 = std::move(e1);
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp
new file mode 100644
index 0000000000000..f05c2d15f3bbe
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class U = T>
+//   constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
+//
+// Constraints:
+// - is_same_v<remove_cvref_t<U>, in_place_t> is false; and
+// - is_same_v<expected, remove_cvref_t<U>> is false; and
+// - remove_cvref_t<U> is not a specialization of unexpected; and
+// - is_constructible_v<T, U> is true.
+//
+// Effects: Direct-non-list-initializes val with std::forward<U>(v).
+//
+// Postconditions: has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of val.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(std::is_constructible_v<std::expected<int, int>, int>);
+
+// is_same_v<remove_cvref_t<U>, in_place_t>
+struct FromJustInplace {
+  FromJustInplace(std::in_place_t);
+};
+static_assert(!std::is_constructible_v<std::expected<FromJustInplace, int>, std::in_place_t>);
+static_assert(!std::is_constructible_v<std::expected<FromJustInplace, int>, std::in_place_t const&>);
+
+// is_same_v<expected, remove_cvref_t<U>>
+// Note that result is true because it is covered by the constructors that take expected
+static_assert(std::is_constructible_v<std::expected<int, int>, std::expected<int, int>&>);
+
+// remove_cvref_t<U> is a specialization of unexpected
+// Note that result is true because it is covered by the constructors that take unexpected
+static_assert(std::is_constructible_v<std::expected<int, int>, std::unexpected<int>&>);
+
+// !is_constructible_v<T, U>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<int, int>, foo>);
+
+// test explicit(!is_convertible_v<U, T>)
+struct NotConvertible {
+  explicit NotConvertible(int);
+};
+static_assert(std::is_convertible_v<int, std::expected<int, int>>);
+static_assert(!std::is_convertible_v<int, std::expected<NotConvertible, int>>);
+
+struct CopyOnly {
+  int i;
+  constexpr CopyOnly(int ii) : i(ii) {}
+  CopyOnly(const CopyOnly&) = default;
+  CopyOnly(CopyOnly&&)      = delete;
+  friend constexpr bool operator==(const CopyOnly& mi, int ii) { return mi.i == ii; }
+};
+
+template <class T>
+constexpr void testInt() {
+  std::expected<T, int> e(5);
+  assert(e.has_value());
+  assert(e.value() == 5);
+}
+
+template <class T>
+constexpr void testLValue() {
+  T t(5);
+  std::expected<T, int> e(t);
+  assert(e.has_value());
+  assert(e.value() == 5);
+}
+
+template <class T>
+constexpr void testRValue() {
+  std::expected<T, int> e(T(5));
+  assert(e.has_value());
+  assert(e.value() == 5);
+}
+
+constexpr bool test() {
+  testInt<int>();
+  testInt<CopyOnly>();
+  testInt<MoveOnly>();
+  testLValue<int>();
+  testLValue<CopyOnly>();
+  testRValue<int>();
+  testRValue<MoveOnly>();
+
+  // Test default template argument.
+  // Without it, the template parameter cannot be deduced from an initializer list
+  {
+    struct Bar {
+      int i;
+      int j;
+      constexpr Bar(int ii, int jj) : i(ii), j(jj) {}
+    };
+
+    std::expected<Bar, int> e({5, 6});
+    assert(e.value().i == 5);
+    assert(e.value().j == 6);
+  }
+
+  // this is a confusing example, but the behaviour
+  // is exactly what is specified in the spec
+  // see https://cplusplus.github.io/LWG/issue3836
+  {
+    struct BaseError {};
+    struct DerivedError : BaseError {};
+
+    std::expected<bool, DerivedError> e1(false);
+    std::expected<bool, BaseError> e2(e1);
+    assert(e2.has_value());
+    assert(e2.value()); // yes, e2 holds "true"
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<Throwing, int> u(5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect.pass.cpp
new file mode 100644
index 0000000000000..ed705d35ee019
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class... Args>
+//   constexpr explicit expected(unexpect_t, Args&&... args);
+//
+// Constraints: is_constructible_v<E, Args...> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<Args>(args)....
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <expected>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(std::is_constructible_v<std::expected<int, int>, std::unexpect_t>);
+static_assert(std::is_constructible_v<std::expected<int, int>, std::unexpect_t, int>);
+
+// !is_constructible_v<T, Args...>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<int, foo>, std::unexpect_t, int>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+static_assert(ImplicitlyConstructible<int, int>);
+
+static_assert(!ImplicitlyConstructible<std::expected<int, int>, std::unexpect_t>);
+static_assert(!ImplicitlyConstructible<std::expected<int, int>, std::unexpect_t, int>);
+
+struct CopyOnly {
+  int i;
+  constexpr CopyOnly(int ii) : i(ii) {}
+  CopyOnly(const CopyOnly&) = default;
+  CopyOnly(CopyOnly&&)      = delete;
+  friend constexpr bool operator==(const CopyOnly& mi, int ii) { return mi.i == ii; }
+};
+
+template <class T>
+constexpr void testInt() {
+  std::expected<int, T> e(std::unexpect, 5);
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+template <class T>
+constexpr void testLValue() {
+  T t(5);
+  std::expected<int, T> e(std::unexpect, t);
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+template <class T>
+constexpr void testRValue() {
+  std::expected<int, T> e(std::unexpect, T(5));
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+constexpr bool test() {
+  testInt<int>();
+  testInt<CopyOnly>();
+  testInt<MoveOnly>();
+  testLValue<int>();
+  testLValue<CopyOnly>();
+  testRValue<int>();
+  testRValue<MoveOnly>();
+
+  // no arg
+  {
+    std::expected<int, int> e(std::unexpect);
+    assert(!e.has_value());
+    assert(e.error() == 0);
+  }
+
+  // one arg
+  {
+    std::expected<int, int> e(std::unexpect, 5);
+    assert(!e.has_value());
+    assert(e.error() == 5);
+  }
+
+  // multi args
+  {
+    std::expected<int, std::tuple<int, short, MoveOnly>> e(std::unexpect, 1, 2, MoveOnly(3));
+    assert(!e.has_value());
+    assert((e.error() == std::tuple<int, short, MoveOnly>(1, 2, MoveOnly(3))));
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<int, Throwing> u(std::unexpect, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect_init_list.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect_init_list.pass.cpp
new file mode 100644
index 0000000000000..20ab1145b767d
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpect_init_list.pass.cpp
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class U, class... Args>
+//   constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
+//
+// Constraints: is_constructible_v<E, initializer_list<U>&, Args...> is true.
+//
+// Effects: Direct-non-list-initializes unex with il, std::forward<Args>(args)....
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <algorithm>
+#include <cassert>
+#include <expected>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(
+    std::is_constructible_v<std::expected<int, std::vector<int>>, std::unexpect_t, std::initializer_list<int>>);
+
+// !is_constructible_v<T, initializer_list<U>&, Args...>
+static_assert(!std::is_constructible_v<std::expected<int, int>, std::unexpect_t, std::initializer_list<int>>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+static_assert(ImplicitlyConstructible<int, int>);
+
+static_assert(
+    !ImplicitlyConstructible<std::expected<int, std::vector<int>>, std::unexpect_t, std::initializer_list<int>>);
+
+template <class... Ts>
+struct Data {
+  std::vector<int> vec_;
+  std::tuple<Ts...> tuple_;
+
+  template <class... Us>
+    requires std::is_constructible_v<std::tuple<Ts...>, Us&&...>
+  constexpr Data(std::initializer_list<int> il, Us&&... us) : vec_(il), tuple_(std::forward<Us>(us)...) {}
+};
+
+constexpr bool test() {
+  // no arg
+  {
+    std::expected<int, Data<>> e(std::unexpect, {1, 2, 3});
+    assert(!e.has_value());
+    auto expectedList = {1, 2, 3};
+    assert(std::ranges::equal(e.error().vec_, expectedList));
+  }
+
+  // one arg
+  {
+    std::expected<int, Data<MoveOnly>> e(std::unexpect, {4, 5, 6}, MoveOnly(5));
+    assert(!e.has_value());
+    auto expectedList = {4, 5, 6};
+    assert((std::ranges::equal(e.error().vec_, expectedList)));
+    assert(std::get<0>(e.error().tuple_) == 5);
+  }
+
+  // multi args
+  {
+    int i = 5;
+    int j = 6;
+    MoveOnly m(7);
+    std::expected<int, Data<int&, int&&, MoveOnly>> e(std::unexpect, {1, 2}, i, std::move(j), std::move(m));
+    assert(!e.has_value());
+    auto expectedList = {1, 2};
+    assert((std::ranges::equal(e.error().vec_, expectedList)));
+    assert(&std::get<0>(e.error().tuple_) == &i);
+    assert(&std::get<1>(e.error().tuple_) == &j);
+    assert(std::get<2>(e.error().tuple_) == 7);
+    assert(m.get() == 0);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(std::initializer_list<int>, int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<int, Throwing> u(std::unexpect, {1, 2}, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.copy.pass.cpp
new file mode 100644
index 0000000000000..09ac91182b3b8
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.copy.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class G>
+//   constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
+//
+// Let GF be const G&
+//
+// Constraints: is_constructible_v<E, GF> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<GF>(e.error()).
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints
+static_assert(std::is_constructible_v<std::expected<int, int>, const std::unexpected<int>&>);
+
+// !is_constructible_v<E, GF>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<int, int>, const std::unexpected<foo>&>);
+static_assert(!std::is_constructible_v<std::expected<int, MoveOnly>, const std::unexpected<MoveOnly>&>);
+
+// explicit(!is_convertible_v<const G&, E>)
+struct NotConvertible {
+  explicit NotConvertible(int);
+};
+static_assert(std::is_convertible_v<const std::unexpected<int>&, std::expected<int, int>>);
+static_assert(!std::is_convertible_v<const std::unexpected<int>&, std::expected<int, NotConvertible>>);
+
+struct MyInt {
+  int i;
+  constexpr MyInt(int ii) : i(ii) {}
+  friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
+};
+
+template <class T>
+constexpr void testUnexpected() {
+  const std::unexpected<int> u(5);
+  std::expected<int, T> e(u);
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+constexpr bool test() {
+  testUnexpected<int>();
+  testUnexpected<MyInt>();
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; }
+  };
+
+  {
+    const std::unexpected<int> u(5);
+    try {
+      [[maybe_unused]] std::expected<int, Throwing> e(u);
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.move.pass.cpp
new file mode 100644
index 0000000000000..9aaaa3fe1a448
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.unexpected.move.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class G>
+//   constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
+//
+// Let GF be G
+//
+// Constraints: is_constructible_v<E, GF> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<GF>(e.error()).
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints
+static_assert(std::is_constructible_v<std::expected<int, int>, std::unexpected<int>>);
+static_assert(std::is_constructible_v<std::expected<int, MoveOnly>, std::unexpected<MoveOnly>>);
+
+// !is_constructible_v<E, GF>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<int, int>, std::unexpected<foo>>);
+
+// explicit(!is_convertible_v<G, E>)
+struct NotConvertible {
+  explicit NotConvertible(int);
+};
+static_assert(std::is_convertible_v<std::unexpected<int>&&, std::expected<int, int>>);
+static_assert(!std::is_convertible_v<std::unexpected<int>&&, std::expected<int, NotConvertible>>);
+
+struct MyInt {
+  int i;
+  constexpr MyInt(int ii) : i(ii) {}
+  friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
+};
+
+template <class Err>
+constexpr void testInt() {
+  std::unexpected<int> u(5);
+  std::expected<int, Err> e(std::move(u));
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+constexpr void testMoveOnly() {
+  std::unexpected<MoveOnly> u(MoveOnly(5));
+  std::expected<int, MoveOnly> e(std::move(u));
+  assert(!e.has_value());
+  assert(e.error() == 5);
+  assert(u.error() == 0);
+}
+
+constexpr bool test() {
+  testInt<int>();
+  testInt<MyInt>();
+  testInt<MoveOnly>();
+  testMoveOnly();
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; }
+  };
+
+  {
+    std::unexpected<int> u(5);
+    try {
+      [[maybe_unused]] std::expected<int, Throwing> e(std::move(u));
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/dtor.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/dtor.pass.cpp
new file mode 100644
index 0000000000000..b758fe0b2bcb4
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/dtor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr ~expected();
+//
+// Effects: If has_value() is true, destroys val, otherwise destroys unex.
+//
+// Remarks: If is_trivially_destructible_v<T> is true, and is_trivially_destructible_v<E> is true,
+// then this destructor is a trivial destructor.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test Remarks: If is_trivially_destructible_v<T> is true, and is_trivially_destructible_v<E> is true,
+// then this destructor is a trivial destructor.
+struct NonTrivial {
+  ~NonTrivial() {}
+};
+
+#if __cpp_concepts >= 202002
+static_assert(std::is_trivially_destructible_v<std::expected<int, int>>);
+#endif
+static_assert(!std::is_trivially_destructible_v<std::expected<NonTrivial, int>>);
+static_assert(!std::is_trivially_destructible_v<std::expected<int, NonTrivial>>);
+static_assert(!std::is_trivially_destructible_v<std::expected<NonTrivial, NonTrivial>>);
+
+struct TrackedDestroy {
+  bool& destroyed;
+  constexpr TrackedDestroy(bool& b) : destroyed(b) {}
+  constexpr ~TrackedDestroy() { destroyed = true; }
+};
+
+constexpr bool test() {
+  // has value
+  {
+    bool valueDestroyed = false;
+    { [[maybe_unused]] std::expected<TrackedDestroy, TrackedDestroy> e(std::in_place, valueDestroyed); }
+    assert(valueDestroyed);
+  }
+
+  // has error
+  {
+    bool errorDestroyed = false;
+    { [[maybe_unused]] std::expected<TrackedDestroy, TrackedDestroy> e(std::unexpect, errorDestroyed); }
+    assert(errorDestroyed);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp
new file mode 100644
index 0000000000000..29945d24ef7a0
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Data {
+  int i;
+  constexpr Data(int ii) : i(ii) {}
+
+  friend constexpr bool operator==(const Data& data, int ii) { return data.i == ii; }
+};
+
+constexpr bool test() {
+  // x.has_value()
+  {
+    const std::expected<Data, int> e1(std::in_place, 5);
+    int i2 = 10;
+    int i3 = 5;
+    assert(e1 != i2);
+    assert(e1 == i3);
+  }
+
+  // !x.has_value()
+  {
+    const std::expected<Data, int> e1(std::unexpect, 5);
+    int i2 = 10;
+    int i3 = 5;
+    assert(e1 != i2);
+    assert(e1 != i3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp
new file mode 100644
index 0000000000000..62f0d6fe57ea9
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class T2, class E2> requires (!is_void_v<T2>)
+//   friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test constraint
+template <class T1, class T2>
+concept CanCompare = requires(T1 t1, T2 t2) { t1 == t2; };
+
+struct Foo{};
+static_assert(!CanCompare<Foo, Foo>);
+
+static_assert(CanCompare<std::expected<int, int>, std::expected<int, int>>);
+static_assert(CanCompare<std::expected<int, int>, std::expected<short, short>>);
+
+// Note this is true because other overloads are unconstrained
+static_assert(CanCompare<std::expected<int, int>, std::expected<void, int>>);
+
+constexpr bool test() {
+  // x.has_value() && y.has_value()
+  {
+    const std::expected<int, int> e1(5);
+    const std::expected<int, int> e2(10);
+    const std::expected<int, int> e3(5);
+    assert(e1 != e2);
+    assert(e1 == e3);
+  }
+
+  // !x.has_value() && y.has_value()
+  {
+    const std::expected<int, int> e1(std::unexpect, 5);
+    const std::expected<int, int> e2(10);
+    const std::expected<int, int> e3(5);
+    assert(e1 != e2);
+    assert(e1 != e3);
+  }
+
+  // x.has_value() && !y.has_value()
+  {
+    const std::expected<int, int> e1(5);
+    const std::expected<int, int> e2(std::unexpect, 10);
+    const std::expected<int, int> e3(std::unexpect, 5);
+    assert(e1 != e2);
+    assert(e1 != e3);
+  }
+
+  // !x.has_value() && !y.has_value()
+  {
+    const std::expected<int, int> e1(std::unexpect, 5);
+    const std::expected<int, int> e2(std::unexpect, 10);
+    const std::expected<int, int> e3(std::unexpect, 5);
+    assert(e1 != e2);
+    assert(e1 == e3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp
new file mode 100644
index 0000000000000..963f39b1cbc2c
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Data {
+  int i;
+  constexpr Data(int ii) : i(ii) {}
+
+  friend constexpr bool operator==(const Data& data, int ii) { return data.i == ii; }
+};
+
+constexpr bool test() {
+  // x.has_value()
+  {
+    const std::expected<Data, Data> e1(std::in_place, 5);
+    std::unexpected<int> un2(10);
+    std::unexpected<int> un3(5);
+    assert(e1 != un2);
+    assert(e1 != un3);
+  }
+
+  // !x.has_value()
+  {
+    const std::expected<Data, Data> e1(std::unexpect, 5);
+    std::unexpected<int> un2(10);
+    std::unexpected<int> un3(5);
+    assert(e1 != un2);
+    assert(e1 == un3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/arrow.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/arrow.pass.cpp
new file mode 100644
index 0000000000000..72fb16609bf96
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/arrow.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const T* operator->() const noexcept;
+// constexpr T* operator->() noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept ArrowNoexcept =
+    requires(T t) {
+      { t.operator->() } noexcept;
+    };
+
+static_assert(!ArrowNoexcept<int>);
+
+static_assert(ArrowNoexcept<std::expected<int, int>>);
+static_assert(ArrowNoexcept<const std::expected<int, int>>);
+
+constexpr bool test() {
+  // const
+  {
+    const std::expected<int, int> e(5);
+    std::same_as<const int*> decltype(auto) x = e.operator->();
+    assert(x == &(e.value()));
+    assert(*x == 5);
+  }
+
+  // non-const
+  {
+    std::expected<int, int> e(5);
+    std::same_as<int*> decltype(auto) x = e.operator->();
+    assert(x == &(e.value()));
+    assert(*x == 5);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/bool.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/bool.pass.cpp
new file mode 100644
index 0000000000000..8daecf3950ec0
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/bool.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr explicit operator bool() const noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept OpBoolNoexcept =
+    requires(T t) {
+      { static_cast<bool>(t) } noexcept;
+    };
+
+struct Foo {};
+static_assert(!OpBoolNoexcept<Foo>);
+
+static_assert(OpBoolNoexcept<std::expected<int, int>>);
+static_assert(OpBoolNoexcept<const std::expected<int, int>>);
+
+// Test explicit
+static_assert(!std::is_convertible_v<std::expected<int, int>, bool>);
+
+constexpr bool test() {
+  // has_value
+  {
+    const std::expected<int, int> e(5);
+    assert(static_cast<bool>(e));
+  }
+
+  // !has_value
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    assert(!static_cast<bool>(e));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/deref.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/deref.pass.cpp
new file mode 100644
index 0000000000000..80bc243fcaefd
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/deref.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const T& operator*() const & noexcept;
+// constexpr T& operator*() & noexcept;
+// constexpr T&& operator*() && noexcept;
+// constexpr const T&& operator*() const && noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept DerefNoexcept =
+    requires(T t) {
+      { std::forward<T>(t).operator*() } noexcept;
+    };
+
+static_assert(!DerefNoexcept<int>);
+
+static_assert(DerefNoexcept<std::expected<int, int>&>);
+static_assert(DerefNoexcept<const std::expected<int, int>&>);
+static_assert(DerefNoexcept<std::expected<int, int>&&>);
+static_assert(DerefNoexcept<const std::expected<int, int>&&>);
+
+constexpr bool test() {
+  // non-const &
+  {
+    std::expected<int, int> e(5);
+    decltype(auto) x = *e;
+    static_assert(std::same_as<decltype(x), int&>);
+    assert(&x == &(e.value()));
+    assert(x == 5);
+  }
+
+  // const &
+  {
+    const std::expected<int, int> e(5);
+    decltype(auto) x = *e;
+    static_assert(std::same_as<decltype(x), const int&>);
+    assert(&x == &(e.value()));
+    assert(x == 5);
+  }
+
+  // non-const &&
+  {
+    std::expected<int, int> e(5);
+    decltype(auto) x = *std::move(e);
+    static_assert(std::same_as<decltype(x), int&&>);
+    assert(&x == &(e.value()));
+    assert(x == 5);
+  }
+
+  // const &&
+  {
+    const std::expected<int, int> e(5);
+    decltype(auto) x = *std::move(e);
+    static_assert(std::same_as<decltype(x), const int&&>);
+    assert(&x == &(e.value()));
+    assert(x == 5);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/error.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/error.pass.cpp
new file mode 100644
index 0000000000000..491e5e6b96b9a
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/error.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const E& error() const & noexcept;
+// constexpr E& error() & noexcept;
+// constexpr E&& error() && noexcept;
+// constexpr const E&& error() const && noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept ErrorNoexcept =
+    requires(T t) {
+      { std::forward<T>(t).error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+
+static_assert(ErrorNoexcept<std::expected<int, int>&>);
+static_assert(ErrorNoexcept<const std::expected<int, int>&>);
+static_assert(ErrorNoexcept<std::expected<int, int>&&>);
+static_assert(ErrorNoexcept<const std::expected<int, int>&&>);
+
+constexpr bool test() {
+  // non-const &
+  {
+    std::expected<int, int> e(std::unexpect, 5);
+    decltype(auto) x = e.error();
+    static_assert(std::same_as<decltype(x), int&>);
+    assert(x == 5);
+  }
+
+  // const &
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    decltype(auto) x = e.error();
+    static_assert(std::same_as<decltype(x), const int&>);
+    assert(x == 5);
+  }
+
+  // non-const &&
+  {
+    std::expected<int, int> e(std::unexpect, 5);
+    decltype(auto) x = std::move(e).error();
+    static_assert(std::same_as<decltype(x), int&&>);
+    assert(x == 5);
+  }
+
+  // const &&
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    decltype(auto) x = std::move(e).error();
+    static_assert(std::same_as<decltype(x), const int&&>);
+    assert(x == 5);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp
new file mode 100644
index 0000000000000..27d657a065699
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/has_value.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr bool has_value() const noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept HasValueNoexcept =
+    requires(T t) {
+      { t.has_value() } noexcept;
+    };
+
+struct Foo {};
+static_assert(!HasValueNoexcept<Foo>);
+
+static_assert(HasValueNoexcept<std::expected<int, int>>);
+static_assert(HasValueNoexcept<const std::expected<int, int>>);
+
+constexpr bool test() {
+  // has_value
+  {
+    const std::expected<int, int> e(5);
+    assert(e.has_value());
+  }
+
+  // !has_value
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    assert(!e.has_value());
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/value.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/value.pass.cpp
new file mode 100644
index 0000000000000..87d74486f280e
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/value.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const T& value() const &;
+// constexpr T& value() &;
+// constexpr T&& value() &&;
+// constexpr const T&& value() const &&;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  // non-const &
+  {
+    std::expected<int, int> e(5);
+    decltype(auto) x = e.value();
+    static_assert(std::same_as<decltype(x), int&>);
+    assert(&x == &(*e));
+    assert(x == 5);
+  }
+
+  // const &
+  {
+    const std::expected<int, int> e(5);
+    decltype(auto) x = e.value();
+    static_assert(std::same_as<decltype(x), const int&>);
+    assert(&x == &(*e));
+    assert(x == 5);
+  }
+
+  // non-const &&
+  {
+    std::expected<int, int> e(5);
+    decltype(auto) x = std::move(e).value();
+    static_assert(std::same_as<decltype(x), int&&>);
+    assert(&x == &(*e));
+    assert(x == 5);
+  }
+
+  // const &&
+  {
+    const std::expected<int, int> e(5);
+    decltype(auto) x = std::move(e).value();
+    static_assert(std::same_as<decltype(x), const int&&>);
+    assert(&x == &(*e));
+    assert(x == 5);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+  // int
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    try {
+      e.value();
+      assert(false);
+    } catch (const std::bad_expected_access<int>& ex) {
+      assert(ex.error() == 5);
+    }
+  }
+
+  // MoveOnly
+  {
+    std::expected<int, MoveOnly> e(std::unexpect, 5);
+    try {
+      std::move(e).value();
+      assert(false);
+    } catch (const std::bad_expected_access<MoveOnly>& ex) {
+      assert(ex.error() == 5);
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/observers/value_or.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/observers/value_or.pass.cpp
new file mode 100644
index 0000000000000..b79b507e52550
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/observers/value_or.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class U> constexpr T value_or(U&& v) const &;
+// template<class U> constexpr T value_or(U&& v) &&;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  // const &, has_value()
+  {
+    const std::expected<int, int> e(5);
+    std::same_as<int> decltype(auto) x = e.value_or(10);
+    assert(x == 5);
+  }
+
+  // const &, !has_value()
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    std::same_as<int> decltype(auto) x = e.value_or(10);
+    assert(x == 10);
+  }
+
+  // &&, has_value()
+  {
+    std::expected<MoveOnly, int> e(std::in_place, 5);
+    std::same_as<MoveOnly> decltype(auto) x = std::move(e).value_or(10);
+    assert(x == 5);
+  }
+
+  // &&, !has_value()
+  {
+    std::expected<MoveOnly, int> e(std::unexpect, 5);
+    std::same_as<MoveOnly> decltype(auto) x = std::move(e).value_or(10);
+    assert(x == 10);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+  // int
+  {
+    const std::expected<int, int> e(std::unexpect, 5);
+    try {
+      e.value();
+      assert(false);
+    } catch (const std::bad_expected_access<int>& ex) {
+      assert(ex.error() == 5);
+    }
+  }
+
+  // MoveOnly
+  {
+    std::expected<int, MoveOnly> e(std::unexpect, 5);
+    try {
+      std::move(e).value();
+      assert(false);
+    } catch (const std::bad_expected_access<MoveOnly>& ex) {
+      assert(ex.error() == 5);
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/swap/free.swap.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/swap/free.swap.pass.cpp
new file mode 100644
index 0000000000000..3ea128a9f19e0
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/swap/free.swap.pass.cpp
@@ -0,0 +1,223 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, clang-15, apple-clang-14
+
+// friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+// Test Constraints:
+struct NotSwappable {
+  NotSwappable operator=(const NotSwappable&) = delete;
+};
+void swap(NotSwappable&, NotSwappable&) = delete;
+
+static_assert(std::is_swappable_v<std::expected<int, int>>);
+
+// !is_swappable_v<T>
+static_assert(!std::is_swappable_v<std::expected<NotSwappable, int>>);
+
+// !is_swappable_v<E>
+static_assert(!std::is_swappable_v<std::expected<int, NotSwappable>>);
+
+struct NotMoveContructible {
+  NotMoveContructible(NotMoveContructible&&) = delete;
+  friend void swap(NotMoveContructible&, NotMoveContructible&) {}
+};
+
+// !is_move_constructible_v<T>
+static_assert(!std::is_swappable_v<std::expected<NotMoveContructible, int>>);
+
+// !is_move_constructible_v<E>
+static_assert(!std::is_swappable_v<std::expected<int, NotMoveContructible>>);
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow&&) noexcept(false);
+  friend void swap(MoveMayThrow&, MoveMayThrow&) noexcept {}
+};
+
+// !is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>
+static_assert(std::is_swappable_v<std::expected<MoveMayThrow, int>>);
+
+// is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(std::is_swappable_v<std::expected<int, MoveMayThrow>>);
+
+// !is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_swappable_v<std::expected<MoveMayThrow, MoveMayThrow>>);
+
+// Test noexcept
+static_assert(std::is_nothrow_swappable_v<std::expected<int, int>>);
+
+// !is_nothrow_move_constructible_v<T>
+static_assert(!std::is_nothrow_swappable_v<std::expected<MoveMayThrow, int>>);
+
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_nothrow_swappable_v<std::expected<int, MoveMayThrow>>);
+
+struct SwapMayThrow {
+  friend void swap(SwapMayThrow&, SwapMayThrow&) noexcept(false) {}
+};
+
+// !is_nothrow_swappable_v<T>
+static_assert(!std::is_nothrow_swappable_v<std::expected<SwapMayThrow, int>>);
+
+// !is_nothrow_swappable_v<E>
+static_assert(!std::is_nothrow_swappable_v<std::expected<int, SwapMayThrow>>);
+
+constexpr bool test() {
+  // this->has_value() && rhs.has_value()
+  {
+    std::expected<ADLSwap, int> x(std::in_place, 5);
+    std::expected<ADLSwap, int> y(std::in_place, 10);
+    swap(x, y);
+
+    assert(x.has_value());
+    assert(x->i == 10);
+    assert(x->adlSwapCalled);
+    assert(y.has_value());
+    assert(y->i == 5);
+    assert(y->adlSwapCalled);
+  }
+
+  // !this->has_value() && !rhs.has_value()
+  {
+    std::expected<int, ADLSwap> x(std::unexpect, 5);
+    std::expected<int, ADLSwap> y(std::unexpect, 10);
+    swap(x, y);
+
+    assert(!x.has_value());
+    assert(x.error().i == 10);
+    assert(x.error().adlSwapCalled);
+    assert(!y.has_value());
+    assert(y.error().i == 5);
+    assert(y.error().adlSwapCalled);
+  }
+
+  // this->has_value() && !rhs.has_value()
+  // && is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<true>> e1(std::in_place, 5);
+    std::expected<TrackedMove<true>, TrackedMove<true>> e2(std::unexpect, 10);
+
+    swap(e1, e2);
+
+    assert(!e1.has_value());
+    assert(e1.error().i == 10);
+    assert(e2.has_value());
+    assert(e2->i == 5);
+
+    assert(e1.error().numberOfMoves == 2);
+    assert(!e1.error().swapCalled);
+    assert(e2->numberOfMoves == 1);
+    assert(!e2->swapCalled);
+  }
+
+  // this->has_value() && !rhs.has_value()
+  // && !is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<false>> e1(std::in_place, 5);
+    std::expected<TrackedMove<true>, TrackedMove<false>> e2(std::unexpect, 10);
+
+    e1.swap(e2);
+
+    assert(!e1.has_value());
+    assert(e1.error().i == 10);
+    assert(e2.has_value());
+    assert(e2->i == 5);
+
+    assert(e1.error().numberOfMoves == 1);
+    assert(!e1.error().swapCalled);
+    assert(e2->numberOfMoves == 2);
+    assert(!e2->swapCalled);
+  }
+
+  // !this->has_value() && rhs.has_value()
+  // && is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<true>> e1(std::unexpect, 10);
+    std::expected<TrackedMove<true>, TrackedMove<true>> e2(std::in_place, 5);
+
+    swap(e1, e2);
+
+    assert(e1.has_value());
+    assert(e1->i == 5);
+    assert(!e2.has_value());
+    assert(e2.error().i == 10);
+
+    assert(e1->numberOfMoves == 1);
+    assert(!e1->swapCalled);
+    assert(e2.error().numberOfMoves == 2);
+    assert(!e2.error().swapCalled);
+  }
+
+  // !this->has_value() && rhs.has_value()
+  // && !is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<false>> e1(std::unexpect, 10);
+    std::expected<TrackedMove<true>, TrackedMove<false>> e2(std::in_place, 5);
+
+    swap(e1, e2);
+
+    assert(e1.has_value());
+    assert(e1->i == 5);
+    assert(!e2.has_value());
+    assert(e2.error().i == 10);
+
+    assert(e1->numberOfMoves == 2);
+    assert(!e1->swapCalled);
+    assert(e2.error().numberOfMoves == 1);
+    assert(!e2.error().swapCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  // !e1.has_value() && e2.has_value()
+  {
+    std::expected<ThrowOnMoveConstruct, int> e1(std::unexpect, 5);
+    std::expected<ThrowOnMoveConstruct, int> e2(std::in_place);
+    try {
+      swap(e1, e2);
+      assert(false);
+    } catch (Except) {
+      assert(!e1.has_value());
+      assert(e1.error() == 5);
+    }
+  }
+
+  // e1.has_value() && !e2.has_value()
+  {
+    std::expected<int, ThrowOnMoveConstruct> e1(5);
+    std::expected<int, ThrowOnMoveConstruct> e2(std::unexpect);
+    try {
+      swap(e1, e2);
+      assert(false);
+    } catch (Except) {
+      assert(e1.has_value());
+      assert(*e1 == 5);
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/swap/member.swap.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/swap/member.swap.pass.cpp
new file mode 100644
index 0000000000000..d2d4a09922092
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.expected/swap/member.swap.pass.cpp
@@ -0,0 +1,239 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr void swap(expected& rhs) noexcept(see below);
+//
+// Constraints:
+// is_swappable_v<T> is true and
+// is_swappable_v<E> is true and
+// is_move_constructible_v<T> && is_move_constructible_v<E> is true, and
+// is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true.
+//
+// Throws: Any exception thrown by the expressions in the Effects.
+// Remarks: The exception specification is equivalent to:
+// is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> &&
+// is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+// Test Constraints:
+template <class T, class E>
+concept HasMemberSwap = requires(std::expected<T, E> x, std::expected<T, E> y) { x.swap(y); };
+
+static_assert(HasMemberSwap<int, int>);
+
+struct NotSwappable {};
+void swap(NotSwappable&, NotSwappable&) = delete;
+
+// !is_swappable_v<T>
+static_assert(!HasMemberSwap<NotSwappable, int>);
+
+// !is_swappable_v<E>
+static_assert(!HasMemberSwap<int, NotSwappable>);
+
+struct NotMoveContructible {
+  NotMoveContructible(NotMoveContructible&&) = delete;
+  friend void swap(NotMoveContructible&, NotMoveContructible&) {}
+};
+
+// !is_move_constructible_v<T>
+static_assert(!HasMemberSwap<NotMoveContructible, int>);
+
+// !is_move_constructible_v<E>
+static_assert(!HasMemberSwap<int, NotMoveContructible>);
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow&&) noexcept(false);
+  friend void swap(MoveMayThrow&, MoveMayThrow&) noexcept {}
+};
+
+// !is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>
+static_assert(HasMemberSwap<MoveMayThrow, int>);
+
+// is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(HasMemberSwap<int, MoveMayThrow>);
+
+// !is_nothrow_move_constructible_v<T> && !is_nothrow_move_constructible_v<E>
+static_assert(!HasMemberSwap<MoveMayThrow, MoveMayThrow>);
+
+// Test noexcept
+template <class T, class E>
+concept MemberSwapNoexcept =
+    requires(std::expected<T, E> x, std::expected<T, E> y) {
+      { x.swap(y) } noexcept;
+    };
+
+static_assert(MemberSwapNoexcept<int, int>);
+
+// !is_nothrow_move_constructible_v<T>
+static_assert(!MemberSwapNoexcept<MoveMayThrow, int>);
+
+// !is_nothrow_move_constructible_v<E>
+static_assert(!MemberSwapNoexcept<int, MoveMayThrow>);
+
+struct SwapMayThrow {
+  friend void swap(SwapMayThrow&, SwapMayThrow&) noexcept(false) {}
+};
+
+// !is_nothrow_swappable_v<T>
+static_assert(!MemberSwapNoexcept<SwapMayThrow, int>);
+
+// !is_nothrow_swappable_v<E>
+static_assert(!MemberSwapNoexcept<int, SwapMayThrow>);
+
+constexpr bool test() {
+  // this->has_value() && rhs.has_value()
+  {
+    std::expected<ADLSwap, int> x(std::in_place, 5);
+    std::expected<ADLSwap, int> y(std::in_place, 10);
+    x.swap(y);
+
+    assert(x.has_value());
+    assert(x->i == 10);
+    assert(x->adlSwapCalled);
+    assert(y.has_value());
+    assert(y->i == 5);
+    assert(y->adlSwapCalled);
+  }
+
+  // !this->has_value() && !rhs.has_value()
+  {
+    std::expected<int, ADLSwap> x(std::unexpect, 5);
+    std::expected<int, ADLSwap> y(std::unexpect, 10);
+    x.swap(y);
+
+    assert(!x.has_value());
+    assert(x.error().i == 10);
+    assert(x.error().adlSwapCalled);
+    assert(!y.has_value());
+    assert(y.error().i == 5);
+    assert(y.error().adlSwapCalled);
+  }
+
+  // this->has_value() && !rhs.has_value()
+  // && is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<true>> e1(std::in_place, 5);
+    std::expected<TrackedMove<true>, TrackedMove<true>> e2(std::unexpect, 10);
+
+    e1.swap(e2);
+
+    assert(!e1.has_value());
+    assert(e1.error().i == 10);
+    assert(e2.has_value());
+    assert(e2->i == 5);
+
+    assert(e1.error().numberOfMoves == 2);
+    assert(!e1.error().swapCalled);
+    assert(e2->numberOfMoves == 1);
+    assert(!e2->swapCalled);
+  }
+
+  // this->has_value() && !rhs.has_value()
+  // && !is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<false>> e1(std::in_place, 5);
+    std::expected<TrackedMove<true>, TrackedMove<false>> e2(std::unexpect, 10);
+
+    e1.swap(e2);
+
+    assert(!e1.has_value());
+    assert(e1.error().i == 10);
+    assert(e2.has_value());
+    assert(e2->i == 5);
+
+    assert(e1.error().numberOfMoves == 1);
+    assert(!e1.error().swapCalled);
+    assert(e2->numberOfMoves == 2);
+    assert(!e2->swapCalled);
+  }
+
+  // !this->has_value() && rhs.has_value()
+  // && is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<true>> e1(std::unexpect, 10);
+    std::expected<TrackedMove<true>, TrackedMove<true>> e2(std::in_place, 5);
+
+    e1.swap(e2);
+
+    assert(e1.has_value());
+    assert(e1->i == 5);
+    assert(!e2.has_value());
+    assert(e2.error().i == 10);
+
+    assert(e1->numberOfMoves == 1);
+    assert(!e1->swapCalled);
+    assert(e2.error().numberOfMoves == 2);
+    assert(!e2.error().swapCalled);
+  }
+
+  // !this->has_value() && rhs.has_value()
+  // && !is_nothrow_move_constructible_v<E>
+  {
+    std::expected<TrackedMove<true>, TrackedMove<false>> e1(std::unexpect, 10);
+    std::expected<TrackedMove<true>, TrackedMove<false>> e2(std::in_place, 5);
+
+    e1.swap(e2);
+
+    assert(e1.has_value());
+    assert(e1->i == 5);
+    assert(!e2.has_value());
+    assert(e2.error().i == 10);
+
+    assert(e1->numberOfMoves == 2);
+    assert(!e1->swapCalled);
+    assert(e2.error().numberOfMoves == 1);
+    assert(!e2.error().swapCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  // !e1.has_value() && e2.has_value()
+  {
+    std::expected<ThrowOnMoveConstruct, int> e1(std::unexpect, 5);
+    std::expected<ThrowOnMoveConstruct, int> e2(std::in_place);
+    try {
+      e1.swap(e2);
+      assert(false);
+    } catch (Except) {
+      assert(!e1.has_value());
+      assert(e1.error() == 5);
+    }
+  }
+
+  // e1.has_value() && !e2.has_value()
+  {
+    std::expected<int, ThrowOnMoveConstruct> e1(5);
+    std::expected<int, ThrowOnMoveConstruct> e2(std::unexpect);
+    try {
+      e1.swap(e2);
+      assert(false);
+    } catch (Except) {
+      assert(e1.has_value());
+      assert(*e1 == 5);
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.copy.pass.cpp
new file mode 100644
index 0000000000000..74f46f0ad9bc4
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.copy.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr unexpected& operator=(const unexpected&) = default;
+
+#include <cassert>
+#include <expected>
+
+struct Error {
+  int i;
+  constexpr Error(int ii) : i(ii) {}
+};
+
+constexpr bool test() {
+  std::unexpected<Error> unex1(4);
+  const std::unexpected<Error> unex2(5);
+  unex1 = unex2;
+  assert(unex1.error().i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.move.pass.cpp
new file mode 100644
index 0000000000000..31573be894d37
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/assign/assign.move.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr unexpected& operator=(unexpected&&) = default;
+
+#include <cassert>
+#include <expected>
+#include <utility>
+
+struct Error {
+  int i;
+  constexpr Error(int ii) : i(ii) {}
+  constexpr Error& operator=(Error&& other) {
+    i       = other.i;
+    other.i = 0;
+    return *this;
+  }
+};
+
+constexpr bool test() {
+  std::unexpected<Error> unex1(4);
+  std::unexpected<Error> unex2(5);
+  unex1 = std::move(unex2);
+  assert(unex1.error().i == 5);
+  assert(unex2.error().i == 0);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/ctad.compile.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/ctad.compile.pass.cpp
new file mode 100644
index 0000000000000..eb23a2f981476
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/ctad.compile.pass.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class E> unexpected(E) -> unexpected<E>;
+
+#include <concepts>
+#include <expected>
+
+struct Foo{};
+
+static_assert(std::same_as<decltype(std::unexpected(5)), std::unexpected<int>>);
+static_assert(std::same_as<decltype(std::unexpected(Foo{})), std::unexpected<Foo>>);
+static_assert(std::same_as<decltype(std::unexpected(std::unexpected<int>(5))), std::unexpected<int>>);

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.copy.pass.cpp
new file mode 100644
index 0000000000000..9a6600232d96b
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.copy.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr unexpected(const unexpected&) = default;
+
+#include <cassert>
+#include <expected>
+
+struct Error {
+  int i;
+  constexpr Error(int ii) : i(ii) {}
+};
+
+constexpr bool test() {
+  const std::unexpected<Error> unex(5);
+  auto unex2 = unex;
+  assert(unex2.error().i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.error.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.error.pass.cpp
new file mode 100644
index 0000000000000..86e903aaf6320
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.error.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class Err = E>
+//   constexpr explicit unexpected(Err&& e);
+//
+// Constraints:
+// - is_same_v<remove_cvref_t<Err>, unexpected> is false; and
+// - is_same_v<remove_cvref_t<Err>, in_place_t> is false; and
+// - is_constructible_v<E, Err> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<Err>(e).
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(std::constructible_from<std::unexpected<int>, int>);
+
+// is_same_v<remove_cvref_t<Err>, unexpected>
+struct CstrFromUnexpected {
+  CstrFromUnexpected(CstrFromUnexpected const&) = delete;
+  CstrFromUnexpected(std::unexpected<CstrFromUnexpected> const&);
+};
+static_assert(!std::constructible_from<std::unexpected<CstrFromUnexpected>, std::unexpected<CstrFromUnexpected>>);
+
+// is_same_v<remove_cvref_t<Err>, in_place_t>
+struct CstrFromInplace {
+  CstrFromInplace(std::in_place_t);
+};
+static_assert(!std::constructible_from<std::unexpected<CstrFromInplace>, std::in_place_t>);
+
+// !is_constructible_v<E, Err>
+struct Foo {};
+static_assert(!std::constructible_from<std::unexpected<Foo>, int>);
+
+// test explicit
+static_assert(std::convertible_to<int, int>);
+static_assert(!std::convertible_to<int, std::unexpected<int>>);
+
+struct Error {
+  int i;
+  constexpr Error(int ii) : i(ii) {}
+  constexpr Error(const Error& other) : i(other.i) {}
+  constexpr Error(Error&& other) : i(other.i) { other.i = 0; }
+  Error(std::initializer_list<Error>) { assert(false); }
+};
+
+constexpr bool test() {
+  // lvalue
+  {
+    Error e(5);
+    std::unexpected<Error> unex(e);
+    assert(unex.error().i == 5);
+    assert(e.i == 5);
+  }
+
+  // rvalue
+  {
+    Error e(5);
+    std::unexpected<Error> unex(std::move(e));
+    assert(unex.error().i == 5);
+    assert(e.i == 0);
+  }
+
+  // Direct-non-list-initializes: does not trigger initializer_list overload
+  {
+    Error e(5);
+    [[maybe_unused]] std::unexpected<Error> unex(e);
+  }
+
+  // Test default template argument.
+  // Without it, the template parameter cannot be deduced from an initializer list
+  {
+    struct Bar {
+      int i;
+      int j;
+      constexpr Bar(int ii, int jj) : i(ii), j(jj) {}
+    };
+    std::unexpected<Bar> ue({5, 6});
+    assert(ue.error().i == 5);
+    assert(ue.error().j == 6);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing() = default;
+    Throwing(const Throwing&) { throw Except{}; }
+  };
+
+  Throwing t;
+  try {
+    std::unexpected<Throwing> u(t);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace.pass.cpp
new file mode 100644
index 0000000000000..5cad5c77cef20
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace.pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class... Args>
+//   constexpr explicit unexpected(in_place_t, Args&&... args);
+//
+// Constraints: is_constructible_v<E, Args...> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<Args>(args)....
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(std::constructible_from<std::unexpected<int>, std::in_place_t, int>);
+
+// !is_constructible_v<E, Args...>
+struct Foo {};
+static_assert(!std::constructible_from<std::unexpected<Foo>, std::in_place_t, int>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+
+static_assert(ImplicitlyConstructible<int, int>);
+static_assert(!ImplicitlyConstructible<std::unexpected<int>, std::in_place_t, int>);
+
+struct Arg {
+  int i;
+  constexpr Arg(int ii) : i(ii) {}
+  constexpr Arg(const Arg& other) : i(other.i) {}
+  constexpr Arg(Arg&& other) : i(other.i) { other.i = 0; }
+};
+
+struct Error {
+  Arg arg;
+  constexpr explicit Error(const Arg& a) : arg(a) {}
+  constexpr explicit Error(Arg&& a) : arg(std::move(a)) {}
+  Error(std::initializer_list<Error>) :arg(0){ assert(false); }
+};
+
+constexpr bool test() {
+  // lvalue
+  {
+    Arg a{5};
+    std::unexpected<Error> unex(std::in_place, a);
+    assert(unex.error().arg.i == 5);
+    assert(a.i == 5);
+  }
+
+  // rvalue
+  {
+    Arg a{5};
+    std::unexpected<Error> unex(std::in_place, std::move(a));
+    assert(unex.error().arg.i == 5);
+    assert(a.i == 0);
+  }
+
+  // Direct-non-list-initializes: does not trigger initializer_list overload
+  {
+    Error e(5);
+    [[maybe_unused]] std::unexpected<Error> unex(std::in_place, e);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; }
+  };
+
+  try {
+    std::unexpected<Throwing> u(std::in_place, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace_init_list.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace_init_list.pass.cpp
new file mode 100644
index 0000000000000..ee9a228cdcfd7
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.inplace_init_list.pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class U, class... Args>
+//   constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args);
+//
+// Constraints: is_constructible_v<E, initializer_list<U>&, Args...> is true.
+//
+// Effects: Direct-non-list-initializes unex with il, std::forward<Args>(args)....
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <algorithm>
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Arg {
+  int i;
+  constexpr Arg(int ii) : i(ii) {}
+  constexpr Arg(const Arg& other) : i(other.i) {}
+  constexpr Arg(Arg&& other) : i(other.i) { other.i = 0; }
+};
+
+struct Error {
+  std::initializer_list<int> list;
+  Arg arg;
+  constexpr explicit Error(std::initializer_list<int> l, const Arg& a) : list(l), arg(a) {}
+  constexpr explicit Error(std::initializer_list<int> l, Arg&& a) : list(l), arg(std::move(a)) {}
+};
+
+// Test Constraints:
+static_assert(std::constructible_from<std::unexpected<Error>, std::in_place_t, std::initializer_list<int>, Arg>);
+
+// !is_constructible_v<E, initializer_list<U>&, Args...>
+struct Foo {};
+static_assert(!std::constructible_from<std::unexpected<Error>, std::in_place_t, std::initializer_list<double>, Arg>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+
+static_assert(ImplicitlyConstructible<int, int>);
+static_assert(!ImplicitlyConstructible<std::unexpected<Error>, std::in_place_t, std::initializer_list<int>, Arg>);
+
+constexpr bool test() {
+  // lvalue
+  {
+    Arg a{5};
+    auto l = {1, 2, 3};
+    std::unexpected<Error> unex(std::in_place, l, a);
+    assert(unex.error().arg.i == 5);
+    assert(std::ranges::equal(unex.error().list, l));
+    assert(a.i == 5);
+  }
+
+  // rvalue
+  {
+    Arg a{5};
+    auto l = {1, 2, 3};
+    std::unexpected<Error> unex(std::in_place, l, std::move(a));
+    assert(unex.error().arg.i == 5);
+    assert(std::ranges::equal(unex.error().list, l));
+    assert(a.i == 0);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(std::initializer_list<int>, int) { throw Except{}; }
+  };
+
+  try {
+    std::unexpected<Throwing> u(std::in_place, {1, 2}, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.move.pass.cpp
new file mode 100644
index 0000000000000..3028dfa25756c
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/ctor/ctor.move.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr unexpected(unexpected&&) = default;
+
+#include <cassert>
+#include <expected>
+#include <utility>
+
+struct Error {
+  int i;
+  constexpr Error(int ii) : i(ii) {}
+  constexpr Error(Error&& other) : i(other.i) {other.i = 0;}
+};
+
+constexpr bool test() {
+  std::unexpected<Error> unex(5);
+  auto unex2 = std::move(unex);
+  assert(unex2.error().i == 5);
+  assert(unex.error().i == 0);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
new file mode 100644
index 0000000000000..4d249df64592f
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class E2>
+// friend constexpr bool operator==(const unexpected& x, const unexpected<E2>& y);
+//
+// Mandates: The expression x.error() == y.error() is well-formed and its result is convertible to bool.
+//
+// Returns: x.error() == y.error().
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+struct Error{
+  int i;
+  friend constexpr bool operator==(const Error&, const Error&) = default;
+};
+
+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);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref.pass.cpp
new file mode 100644
index 0000000000000..8cfe555f70131
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const E& error() const & noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+template <class T>
+concept ErrorNoexcept =
+    requires(const T& t) {
+      { t.error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+static_assert(ErrorNoexcept<std::unexpected<int>>);
+
+constexpr bool test() {
+  const std::unexpected<int> unex(5);
+  decltype(auto) i = unex.error();
+  static_assert(std::same_as<decltype(i), const int&>);
+  assert(i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref_ref.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref_ref.pass.cpp
new file mode 100644
index 0000000000000..ffd8ed8e209a0
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.const_ref_ref.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const E&& error() const && noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+template <class T>
+concept ErrorNoexcept =
+    requires(const T&& t) {
+      { std::move(t).error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+static_assert(ErrorNoexcept<std::unexpected<int>>);
+
+constexpr bool test() {
+  const std::unexpected<int> unex(5);
+  decltype(auto) i = std::move(unex).error();
+  static_assert(std::same_as<decltype(i), const int&&>);
+  assert(i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref.pass.cpp
new file mode 100644
index 0000000000000..4f22eb4773e6e
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr E& error() & noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+template <class T>
+concept ErrorNoexcept =
+    requires(T& t) {
+      { t.error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+static_assert(ErrorNoexcept<std::unexpected<int>>);
+
+constexpr bool test() {
+  std::unexpected<int> unex(5);
+  decltype(auto) i = unex.error();
+  static_assert(std::same_as<decltype(i), int&>);
+  assert(i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref_ref.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref_ref.pass.cpp
new file mode 100644
index 0000000000000..415435b921185
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/observer/error.ref_ref.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr E&& error() && noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+template <class T>
+concept ErrorNoexcept =
+    requires(T&& t) {
+      { std::move(t).error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+static_assert(ErrorNoexcept<std::unexpected<int>>);
+
+constexpr bool test() {
+  std::unexpected<int> unex(5);
+  decltype(auto) i = std::move(unex).error();
+  static_assert(std::same_as<decltype(i), int&&>);
+  assert(i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.free.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.free.pass.cpp
new file mode 100644
index 0000000000000..b70400ae3fb43
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.free.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
+//
+// Constraints: is_swappable_v<E> is true.
+//
+// Effects: Equivalent to x.swap(y).
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+// test noexcept
+struct NoexceptSwap {
+  friend void swap(NoexceptSwap&, NoexceptSwap&) noexcept;
+};
+
+struct MayThrowSwap {
+  friend void swap(MayThrowSwap&, MayThrowSwap&);
+};
+
+template <class T>
+concept ADLSwapNoexcept =
+    requires(T& t1, T& t2) {
+      { swap(t1, t2) } noexcept;
+    };
+
+static_assert(ADLSwapNoexcept<std::unexpected<NoexceptSwap>>);
+static_assert(!ADLSwapNoexcept<std::unexpected<MayThrowSwap>>);
+
+// test constraint
+struct NonSwappable {
+  NonSwappable& operator=(const NonSwappable&) = delete;
+};
+
+static_assert(std::is_swappable_v<std::unexpected<int>>);
+static_assert(std::is_swappable_v<std::unexpected<MayThrowSwap>>);
+static_assert(!std::is_swappable_v<std::unexpected<NonSwappable>>);
+
+struct ADLSwap {
+  constexpr ADLSwap(int ii) : i(ii) {}
+  ADLSwap& operator=(const ADLSwap&) = delete;
+  int i;
+  constexpr friend void swap(ADLSwap& x, ADLSwap& y) { std::swap(x.i, y.i); }
+};
+
+constexpr bool test() {
+  std::unexpected<ADLSwap> unex1(5);
+  std::unexpected<ADLSwap> unex2(6);
+  swap(unex1, unex2);
+  assert(unex1.error().i == 6);
+  assert(unex2.error().i == 5);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.member.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.member.pass.cpp
new file mode 100644
index 0000000000000..d77870e648ece
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/swap/swap.member.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
+//
+// Mandates: is_swappable_v<E> is true.
+//
+// Effects: Equivalent to: using std::swap; swap(unex, other.unex);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <utility>
+
+// test noexcept
+struct NoexceptSwap {
+  friend void swap(NoexceptSwap&, NoexceptSwap&) noexcept;
+};
+
+struct MayThrowSwap {
+  friend void swap(MayThrowSwap&, MayThrowSwap&);
+};
+
+template <class T>
+concept MemberSwapNoexcept =
+    requires(T& t1, T& t2) {
+      { t1.swap(t2) } noexcept;
+    };
+
+static_assert(MemberSwapNoexcept<std::unexpected<NoexceptSwap>>);
+static_assert(!MemberSwapNoexcept<std::unexpected<MayThrowSwap>>);
+
+struct ADLSwap {
+  constexpr ADLSwap(int ii) : i(ii) {}
+  ADLSwap& operator=(const ADLSwap&) = delete;
+  int i;
+  constexpr friend void swap(ADLSwap& x, ADLSwap& y) { std::swap(x.i, y.i); }
+};
+
+constexpr bool test() {
+  // using std::swap;
+  {
+    std::unexpected<int> unex1(5);
+    std::unexpected<int> unex2(6);
+    unex1.swap(unex2);
+    assert(unex1.error() == 6);
+    assert(unex2.error() == 5);
+  }
+
+  // adl swap
+  {
+    std::unexpected<ADLSwap> unex1(5);
+    std::unexpected<ADLSwap> unex2(6);
+    unex1.swap(unex2);
+    assert(unex1.error().i == 6);
+    assert(unex2.error().i == 5);
+  }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/assign/assign.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/assign/assign.copy.pass.cpp
new file mode 100644
index 0000000000000..00af3264532f1
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/assign/assign.copy.pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr expected& operator=(const expected& rhs);
+//
+// Effects:
+// - If this->has_value() && rhs.has_value() is true, no effects.
+// - Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), rhs.unex); has_val = false;
+// - Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
+// - Otherwise, equivalent to unex = rhs.error().
+//
+// Returns: *this.
+//
+// Remarks: This operator is defined as deleted unless is_copy_assignable_v<E> is true and is_copy_constructible_v<E> is true.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotCopyConstructible {
+  NotCopyConstructible(const NotCopyConstructible&)            = delete;
+  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+// Test constraints
+static_assert(std::is_copy_assignable_v<std::expected<void, int>>);
+
+// !is_copy_assignable_v<E>
+static_assert(!std::is_copy_assignable_v<std::expected<void, NotCopyAssignable>>);
+
+// !is_copy_constructible_v<E>
+static_assert(!std::is_copy_assignable_v<std::expected<void, NotCopyConstructible>>);
+
+constexpr bool test() {
+  // If this->has_value() && rhs.has_value() is true, no effects.
+  {
+    std::expected<void, int> e1;
+    std::expected<void, int> e2;
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<void, int>&>);
+    assert(&x == &e1);
+    assert(e1.has_value());
+  }
+
+  // Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), rhs.unex); has_val = false;
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e1;
+    std::expected<void, Traced> e2(std::unexpect, state, 5);
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e1);
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 5);
+
+    assert(state.copyCtorCalled);
+  }
+
+  // Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e1(std::unexpect, state, 5);
+    std::expected<void, Traced> e2;
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e1);
+    assert(e1.has_value());
+
+    assert(state.dtorCalled);
+  }
+
+  // Otherwise, equivalent to unex = rhs.error().
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e1(std::unexpect, state, 5);
+    std::expected<void, Traced> e2(std::unexpect, state, 10);
+    decltype(auto) x = (e1 = e2);
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e1);
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+
+    assert(state.copyAssignCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<void, ThrowOnCopyConstruct> e1(std::in_place);
+  std::expected<void, ThrowOnCopyConstruct> e2(std::unexpect);
+  try {
+    e1 = e2;
+    assert(false);
+  } catch (Except) {
+    assert(e1.has_value());
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/assign/assign.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/assign/assign.move.pass.cpp
new file mode 100644
index 0000000000000..878908d8d8ec4
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/assign/assign.move.pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr expected& operator=(expected&& rhs) noexcept(see below);
+//
+// Effects:
+// - If this->has_value() && rhs.has_value() is true, no effects.
+// - Otherwise, if this->has_value() is true, equivalent to:
+//   construct_at(addressof(unex), std::move(rhs.unex));
+//   has_val = false;
+// - Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
+// - Otherwise, equivalent to unex = std::move(rhs.error()).
+//
+// Returns: *this.
+//
+// Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>.
+//
+// This operator is defined as deleted unless is_move_constructible_v<E> is true and is_move_assignable_v<E> is true.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotMoveConstructible {
+  NotMoveConstructible(NotMoveConstructible&&)            = delete;
+  NotMoveConstructible& operator=(NotMoveConstructible&&) = default;
+};
+
+struct NotMoveAssignable {
+  NotMoveAssignable(NotMoveAssignable&&)            = default;
+  NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
+};
+
+// Test constraints
+static_assert(std::is_move_assignable_v<std::expected<void, int>>);
+
+// !is_move_assignable_v<E>
+static_assert(!std::is_move_assignable_v<std::expected<void, NotMoveAssignable>>);
+
+// !is_move_constructible_v<E>
+static_assert(!std::is_move_assignable_v<std::expected<void, NotMoveConstructible>>);
+
+// Test noexcept
+struct MoveCtorMayThrow {
+  MoveCtorMayThrow(MoveCtorMayThrow&&) noexcept(false) {}
+  MoveCtorMayThrow& operator=(MoveCtorMayThrow&&) noexcept = default;
+};
+
+struct MoveAssignMayThrow {
+  MoveAssignMayThrow(MoveAssignMayThrow&&) noexcept = default;
+  MoveAssignMayThrow& operator=(MoveAssignMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test noexcept
+static_assert(std::is_nothrow_move_assignable_v<std::expected<void, int>>);
+
+// !is_nothrow_move_assignable_v<E>
+static_assert(!std::is_nothrow_move_assignable_v<std::expected<void, MoveAssignMayThrow>>);
+
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_nothrow_move_assignable_v<std::expected<void, MoveCtorMayThrow>>);
+
+constexpr bool test() {
+  // If this->has_value() && rhs.has_value() is true, no effects.
+  {
+    std::expected<void, int> e1;
+    std::expected<void, int> e2;
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<void, int>&>);
+    assert(&x == &e1);
+    assert(e1.has_value());
+  }
+
+  // Otherwise, if this->has_value() is true, equivalent to:
+  // construct_at(addressof(unex), std::move(rhs.unex));
+  // has_val = false;
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e1;
+    std::expected<void, Traced> e2(std::unexpect, state, 5);
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e1);
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 5);
+
+    assert(state.moveCtorCalled);
+  }
+
+  // Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e1(std::unexpect, state, 5);
+    std::expected<void, Traced> e2;
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e1);
+    assert(e1.has_value());
+
+    assert(state.dtorCalled);
+  }
+
+  // Otherwise, equivalent to unex = rhs.error().
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e1(std::unexpect, state, 5);
+    std::expected<void, Traced> e2(std::unexpect, state, 10);
+    decltype(auto) x = (e1 = std::move(e2));
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e1);
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+
+    assert(state.moveAssignCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<void, ThrowOnMoveConstruct> e1(std::in_place);
+  std::expected<void, ThrowOnMoveConstruct> e2(std::unexpect);
+  try {
+    e1 = std::move(e2);
+    assert(false);
+  } catch (Except) {
+    assert(e1.has_value());
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.copy.pass.cpp
new file mode 100644
index 0000000000000..3d8466dbc082f
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.copy.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class G>
+//   constexpr expected& operator=(const unexpected<G>& e);
+//
+// Let GF be const G&
+//
+// Constraints: is_constructible_v<E, GF> is true and is_assignable_v<E&, GF> is true.
+//
+// Effects:
+// - If has_value() is true, equivalent to:
+//   construct_at(addressof(unex), std::forward<GF>(e.error()));
+//   has_val = false;
+// - Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+//
+// Returns: *this.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotCopyConstructible {
+  NotCopyConstructible(const NotCopyConstructible&)            = delete;
+  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow const&)            = default;
+  MoveMayThrow& operator=(const MoveMayThrow&) = default;
+  MoveMayThrow(MoveMayThrow&&) noexcept(false) {}
+  MoveMayThrow& operator=(MoveMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test constraints
+static_assert(std::is_assignable_v<std::expected<void, int>&, const std::unexpected<int>&>);
+
+// !is_constructible_v<E, GF>
+static_assert(
+    !std::is_assignable_v<std::expected<void, NotCopyConstructible>&, const std::unexpected<NotCopyConstructible>&>);
+
+// !is_assignable_v<E&, GF>
+static_assert(
+    !std::is_assignable_v<std::expected<void, NotCopyAssignable>&, const std::unexpected<NotCopyAssignable>&>);
+
+constexpr bool test() {
+  // - If has_value() is true, equivalent to:
+  //   construct_at(addressof(unex), std::forward<GF>(e.error()));
+  //   has_val = false;
+  {
+    Traced::state state{};
+    std::expected<void, Traced> e;
+    std::unexpected<Traced> un(std::in_place, state, 5);
+    decltype(auto) x = (e = un);
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e);
+    assert(!e.has_value());
+    assert(e.error().data_ == 5);
+
+    assert(state.copyCtorCalled);
+  }
+
+  // - Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+  {
+    Traced::state state1{};
+    Traced::state state2{};
+    std::expected<void, Traced> e(std::unexpect, state1, 5);
+    std::unexpected<Traced> un(std::in_place, state2, 10);
+    decltype(auto) x = (e = un);
+    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
+    assert(&x == &e);
+    assert(!e.has_value());
+    assert(e.error().data_ == 10);
+
+    assert(state1.copyAssignCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<void, ThrowOnCopyConstruct> e1(std::in_place);
+  std::unexpected<ThrowOnCopyConstruct> un(std::in_place);
+  try {
+    e1 = un;
+    assert(false);
+  } catch (Except) {
+    assert(e1.has_value());
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.move.pass.cpp
new file mode 100644
index 0000000000000..e07fb5c000c83
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/assign/assign.unexpected.move.pass.cpp
@@ -0,0 +1,199 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class G>
+//   constexpr expected& operator=(unexpected<G>&& e);
+//
+// Let GF be G
+// Constraints:
+// - is_constructible_v<E, GF> is true; and
+// - is_assignable_v<E&, GF> is true; and
+// - is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
+//   is_nothrow_move_constructible_v<E> is true.
+//
+// Effects:
+// - If has_value() is true, equivalent to:
+//   reinit-expected(unex, val, std::forward<GF>(e.error()));
+//   has_val = false;
+// - Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+// Returns: *this.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+struct NotMoveConstructible {
+  NotMoveConstructible(NotMoveConstructible&&)            = delete;
+  NotMoveConstructible& operator=(NotMoveConstructible&&) = default;
+};
+
+struct NotMoveAssignable {
+  NotMoveAssignable(NotMoveAssignable&&)            = default;
+  NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow const&)            = default;
+  MoveMayThrow& operator=(const MoveMayThrow&) = default;
+  MoveMayThrow(MoveMayThrow&&) noexcept(false) {}
+  MoveMayThrow& operator=(MoveMayThrow&&) noexcept(false) { return *this; }
+};
+
+// Test constraints
+static_assert(std::is_assignable_v<std::expected<int, int>&, std::unexpected<int>&&>);
+
+// !is_constructible_v<E, GF>
+static_assert(
+    !std::is_assignable_v<std::expected<int, NotMoveConstructible>&, std::unexpected<NotMoveConstructible>&&>);
+
+// !is_assignable_v<E&, GF>
+static_assert(!std::is_assignable_v<std::expected<int, NotMoveAssignable>&, std::unexpected<NotMoveAssignable>&&>);
+
+template <bool moveNoexcept, bool convertNoexcept>
+struct MaybeNoexcept {
+  explicit MaybeNoexcept(int) noexcept(convertNoexcept);
+  MaybeNoexcept(MaybeNoexcept&&) noexcept(moveNoexcept);
+  MaybeNoexcept& operator=(MaybeNoexcept&&) = default;
+  MaybeNoexcept& operator=(int);
+};
+
+// !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<true, false>>&,
+                                   std::unexpected<int>&&>);
+
+// is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, true>>&,
+                                   std::unexpected<int>&&>);
+
+// !is_nothrow_constructible_v<E, GF> && is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(std::is_assignable_v<std::expected<MaybeNoexcept<true, true>, MaybeNoexcept<false, false>>&,
+                                   std::unexpected<int>&&>);
+
+// !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<T> &&
+// !is_nothrow_move_constructible_v<E>
+static_assert(!std::is_assignable_v<std::expected<MaybeNoexcept<false, false>, MaybeNoexcept<false, false>>&,
+                                    std::unexpected<int>&&>);
+
+constexpr bool test() {
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // is_nothrow_constructible_v<E, GF>
+  //
+  //  In this case, it should call the branch
+  //    destroy_at(addressof(oldval));
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, BothNoexcept> e(std::in_place, oldState, 5);
+    std::unexpected<int> un(10);
+    decltype(auto) x = (e = std::move(un));
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, BothNoexcept>&>);
+    assert(&x == &e);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e.error().movedFromInt);
+  }
+
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // !is_nothrow_constructible_v<E, GF> && is_nothrow_move_constructible_v<E>
+  //
+  //  In this case, it should call the branch
+  //  T tmp(std::forward<Args>(args)...);
+  //  destroy_at(addressof(oldval));
+  //  construct_at(addressof(newval), std::move(tmp));
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, MoveNoexceptConvThrow> e(std::in_place, oldState, 5);
+    std::unexpected<int> un(10);
+    decltype(auto) x = (e = std::move(un));
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, MoveNoexceptConvThrow>&>);
+    assert(&x == &e);
+
+    assert(!oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(!e.error().movedFromInt);
+    assert(e.error().movedFromTmp);
+  }
+
+  // - If has_value() is true, equivalent to:
+  //   reinit-expected(unex, val, std::forward<GF>(e.error()));
+  // !is_nothrow_constructible_v<E, GF> && !is_nothrow_move_constructible_v<E>
+  // is_nothrow_move_constructible_v<T>
+  //
+  //  In this case, it should call the branch
+  //  U tmp(std::move(oldval));
+  //  destroy_at(addressof(oldval));
+  //  try {
+  //    construct_at(addressof(newval), std::forward<Args>(args)...);
+  //  } catch (...) {
+  //    construct_at(addressof(oldval), std::move(tmp));
+  //    throw;
+  //  }
+  {
+    BothNoexcept::state oldState{};
+    std::expected<BothNoexcept, BothMayThrow> e(std::in_place, oldState, 5);
+    std::unexpected<int> un(10);
+    decltype(auto) x = (e = std::move(un));
+    static_assert(std::same_as<decltype(x), std::expected<BothNoexcept, BothMayThrow>&>);
+    assert(&x == &e);
+
+    assert(oldState.moveCtorCalled);
+    assert(oldState.dtorCalled);
+    assert(e.error().movedFromInt);
+  }
+
+  // Otherwise, equivalent to: unex = std::forward<GF>(e.error());
+  {
+    Traced::state oldState{};
+    Traced::state newState{};
+    std::expected<int, Traced> e1(std::unexpect, oldState, 5);
+    std::unexpected<Traced> e(std::in_place, newState, 10);
+    decltype(auto) x = (e1 = std::move(e));
+    static_assert(std::same_as<decltype(x), std::expected<int, Traced >&>);
+    assert(&x == &e1);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(oldState.moveAssignCalled);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  std::expected<void, ThrowOnMoveConstruct> e1(std::in_place);
+  std::unexpected<ThrowOnMoveConstruct> un(std::in_place);
+  try {
+    e1 = std::move(un);
+    assert(false);
+  } catch (Except) {
+    assert(e1.has_value());
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/assign/emplace.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/assign/emplace.pass.cpp
new file mode 100644
index 0000000000000..b3aa5f70f962a
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/assign/emplace.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr void emplace() noexcept;
+//
+// Effects: If has_value() is false, destroys unex and sets has_val to true.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+template <class T>
+concept EmplaceNoexcept =
+    requires(T t) {
+      { t.emplace() } noexcept;
+    };
+static_assert(!EmplaceNoexcept<int>);
+
+static_assert(EmplaceNoexcept<std::expected<void, int>>);
+
+constexpr bool test() {
+  // has_value
+  {
+    std::expected<void, int> e;
+    e.emplace();
+    assert(e.has_value());
+  }
+
+  // !has_value
+  {
+    Traced::state state{};
+    std::expected<int, Traced> e(std::unexpect, state, 5);
+    e.emplace();
+
+    assert(state.dtorCalled);
+    assert(e.has_value());
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.copy.pass.cpp
new file mode 100644
index 0000000000000..40f8efa5f94bf
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.copy.pass.cpp
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class U, class G>
+//   constexpr explicit(!is_convertible_v<const G&, E>) expected(const expected<U, G>& rhs);
+//
+// Let GF be const G&
+//
+// Constraints:
+// - is_void_v<U> is true; and
+// - is_constructible_v<E, GF> is true; and
+// - is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, expected<U, G>> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>> is false.
+//
+// Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std::forward<GF>(rhs.error()).
+//
+// Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test Constraints:
+template <class T1, class Err1, class T2, class Err2>
+concept canCstrFromExpected = std::is_constructible_v<std::expected<T1, Err1>, const std::expected<T2, Err2>&>;
+
+struct CtorFromInt {
+  CtorFromInt(int);
+};
+
+static_assert(canCstrFromExpected<void, CtorFromInt, void, int>);
+
+struct NoCtorFromInt {};
+
+// !is_void_v<E>
+static_assert(!canCstrFromExpected<void, int, int, int>);
+
+// !is_constructible_v<E, GF>
+static_assert(!canCstrFromExpected<void, NoCtorFromInt, void, int>);
+
+template <class T>
+struct CtorFrom {
+  explicit CtorFrom(int)
+    requires(!std::same_as<T, int>);
+  explicit CtorFrom(T);
+  explicit CtorFrom(auto&&) = delete;
+};
+
+// Note for below 4 tests, because their E is constructible from cvref of std::expected<void, int>,
+// unexpected<E> will be constructible from cvref of std::expected<void, int>
+// is_constructible_v<unexpected<E>, expected<U, G>&>
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int>&>, void, int>);
+
+// is_constructible_v<unexpected<E>, expected<U, G>>
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int>&&>, void, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>&> is false
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int> const&>, void, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>>
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int> const&&>, void, int>);
+
+// test explicit
+static_assert(std::is_convertible_v<const std::expected<void, int>&, std::expected<void, long>>);
+
+// !is_convertible_v<GF, E>.
+static_assert(std::is_constructible_v<std::expected<void, CtorFrom<int>>, const std::expected<void, int>&>);
+static_assert(!std::is_convertible_v<const std::expected<void, int>&, std::expected<void, CtorFrom<int>>>);
+
+struct Data {
+  int i;
+  constexpr Data(int ii) : i(ii) {}
+};
+
+constexpr bool test() {
+  // convert the error
+  {
+    const std::expected<void, int> e1(std::unexpect, 5);
+    std::expected<void, Data> e2 = e1;
+    assert(!e2.has_value());
+    assert(e2.error().i == 5);
+    assert(!e1.has_value());
+    assert(e1.error() == 5);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct ThrowingInt {
+    ThrowingInt(int) { throw Except{}; }
+  };
+
+  // throw on converting error
+  {
+    const std::expected<void, int> e1(std::unexpect);
+    try {
+      [[maybe_unused]] std::expected<void, ThrowingInt> e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.move.pass.cpp
new file mode 100644
index 0000000000000..b28fc7a03bb34
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.convert.move.pass.cpp
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class U, class G>
+//   constexpr explicit(!is_convertible_v<G, E>) expected(expected<U, G>&& rhs);
+//
+// Let GF be G
+//
+// Constraints:
+// - is_void_v<U> is true; and
+// - is_constructible_v<E, GF> is true; and
+// - is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, expected<U, G>> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
+// - is_constructible_v<unexpected<E>, const expected<U, G>> is false.
+//
+// Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std::forward<GF>(rhs.error()).
+//
+// Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+template <class T1, class Err1, class T2, class Err2>
+concept canCstrFromExpected = std::is_constructible_v<std::expected<T1, Err1>, std::expected<T2, Err2>&&>;
+
+struct CtorFromInt {
+  CtorFromInt(int);
+};
+
+static_assert(canCstrFromExpected<void, CtorFromInt, void, int>);
+
+struct NoCtorFromInt {};
+
+// !is_void_v<U>
+static_assert(!canCstrFromExpected<void, int, int, int>);
+
+// !is_constructible_v<E, GF>
+static_assert(!canCstrFromExpected<void, NoCtorFromInt, void, int>);
+
+template <class T>
+struct CtorFrom {
+  explicit CtorFrom(int)
+    requires(!std::same_as<T, int>);
+  explicit CtorFrom(T);
+  explicit CtorFrom(auto&&) = delete;
+};
+
+// Note for below 4 tests, because their E is constructible from cvref of std::expected<void, int>,
+// unexpected<E> will be constructible from cvref of std::expected<void, int>
+// is_constructible_v<unexpected<E>, expected<U, G>&>
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int>&>, void, int>);
+
+// is_constructible_v<unexpected<E>, expected<U, G>>
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int>&&>, void, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>&> is false
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int> const&>, void, int>);
+
+// is_constructible_v<unexpected<E>, const expected<U, G>>
+static_assert(!canCstrFromExpected<void, CtorFrom<std::expected<void, int> const&&>, void, int>);
+
+// test explicit
+static_assert(std::is_convertible_v<std::expected<void, int>&&, std::expected<void, long>>);
+
+// !is_convertible_v<GF, E>.
+static_assert(std::is_constructible_v<std::expected<void, CtorFrom<int>>, std::expected<void, int>&&>);
+static_assert(!std::is_convertible_v<std::expected<void, int>&&, std::expected<void, CtorFrom<int>>>);
+
+struct Data {
+  MoveOnly data;
+  constexpr Data(MoveOnly&& m) : data(std::move(m)) {}
+};
+
+constexpr bool test() {
+  // convert the error
+  {
+    std::expected<void, MoveOnly> e1(std::unexpect, 5);
+    std::expected<void, Data> e2 = std::move(e1);
+    assert(!e2.has_value());
+    assert(e2.error().data.get() == 5);
+    assert(!e1.has_value());
+    assert(e1.error().get() == 0);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct ThrowingInt {
+    ThrowingInt(int) { throw Except{}; }
+  };
+
+  // throw on converting error
+  {
+    const std::expected<void, int> e1(std::unexpect);
+    try {
+      [[maybe_unused]] std::expected<void, ThrowingInt> e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.copy.pass.cpp
new file mode 100644
index 0000000000000..f11fb737aea31
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.copy.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr expected(const expected& rhs);
+//
+// Effects: If rhs.has_value() is false, direct-non-list-initializes unex with rhs.error().
+//
+// Postconditions: rhs.has_value() == this->has_value().
+//
+// Throws: Any exception thrown by the initialization of unex.
+//
+// Remarks:
+// - This constructor is defined as deleted unless is_copy_constructible_v<E> is true.
+// - This constructor is trivial if is_trivially_copy_constructible_v<E> is true.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct NonCopyable {
+  NonCopyable(const NonCopyable&) = delete;
+};
+
+struct CopyableNonTrivial {
+  int i;
+  constexpr CopyableNonTrivial(int ii) : i(ii) {}
+  constexpr CopyableNonTrivial(const CopyableNonTrivial& o) { i = o.i; }
+  friend constexpr bool operator==(const CopyableNonTrivial&, const CopyableNonTrivial&) = default;
+};
+
+// Test: This constructor is defined as deleted unless is_copy_constructible_v<E> is true.
+static_assert(std::is_copy_constructible_v<std::expected<void, int>>);
+static_assert(std::is_copy_constructible_v<std::expected<void, CopyableNonTrivial>>);
+static_assert(!std::is_copy_constructible_v<std::expected<void, NonCopyable>>);
+
+// Test: This constructor is trivial if is_trivially_copy_constructible_v<E> is true.
+#if __cpp_concepts >= 202002
+static_assert(std::is_trivially_copy_constructible_v<std::expected<void, int>>);
+#endif
+static_assert(!std::is_trivially_copy_constructible_v<std::expected<void, CopyableNonTrivial>>);
+
+constexpr bool test() {
+  // copy the error non-trivial
+  {
+    const std::expected<void, CopyableNonTrivial> e1(std::unexpect, 5);
+    auto e2 = e1;
+    assert(!e2.has_value());
+    assert(e2.error().i == 5);
+  }
+
+  // copy the error trivial
+  {
+    const std::expected<void, int> e1(std::unexpect, 5);
+    auto e2 = e1;
+    assert(!e2.has_value());
+    assert(e2.error() == 5);
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing() = default;
+    Throwing(const Throwing&) { throw Except{}; }
+  };
+
+  // throw on copying error
+  {
+    const std::expected<void, Throwing> e1(std::unexpect);
+    try {
+      [[maybe_unused]] auto e2 = e1;
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.default.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.default.pass.cpp
new file mode 100644
index 0000000000000..e05cf027719b7
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.default.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr expected() noexcept;
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// Test noexcept
+
+struct NoDefaultCtor {
+  constexpr NoDefaultCtor() = delete;
+};
+
+static_assert(std::is_nothrow_default_constructible_v<std::expected<void, int>>);
+static_assert(std::is_nothrow_default_constructible_v<std::expected<void, NoDefaultCtor>>);
+
+struct MyInt {
+  int i;
+  friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
+};
+
+constexpr bool test() {
+  // default constructible
+  {
+    std::expected<void, int> e;
+    assert(e.has_value());
+  }
+
+  // non-default constructible
+  {
+    std::expected<void, NoDefaultCtor> e;
+    assert(e.has_value());
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.inplace.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.inplace.pass.cpp
new file mode 100644
index 0000000000000..848e61dd60779
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.inplace.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr explicit expected(in_place_t) noexcept;
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+// test explicit
+static_assert(std::is_constructible_v<std::expected<void, int>, std::in_place_t>);
+static_assert(!std::is_convertible_v<std::in_place_t, std::expected<void, int>>);
+
+// test noexcept
+static_assert(std::is_nothrow_constructible_v<std::expected<void, int>, std::in_place_t>);
+
+constexpr bool test() {
+  std::expected<void, int> e(std::in_place);
+  assert(e.has_value());
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.move.pass.cpp
new file mode 100644
index 0000000000000..f1c42f44528a5
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.move.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
+//
+// Constraints: is_move_constructible_v<E> is true.
+//
+// Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std::move(rhs.error()).
+//
+// Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
+//
+// Throws: Any exception thrown by the initialization of unex.
+//
+// Remarks: This constructor is trivial if is_trivially_move_constructible_v<E> is true.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct NonMovable {
+  NonMovable(NonMovable&&) = delete;
+};
+
+struct MovableNonTrivial {
+  int i;
+  constexpr MovableNonTrivial(int ii) : i(ii) {}
+  constexpr MovableNonTrivial(MovableNonTrivial&& o) : i(o.i) { o.i = 0; }
+  friend constexpr bool operator==(const MovableNonTrivial&, const MovableNonTrivial&) = default;
+};
+
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow&&) {}
+};
+
+// Test Constraints:
+// - is_move_constructible_v<E> is true.
+static_assert(std::is_move_constructible_v<std::expected<void, int>>);
+static_assert(std::is_move_constructible_v<std::expected<void, MovableNonTrivial>>);
+static_assert(!std::is_move_constructible_v<std::expected<void, NonMovable>>);
+
+// Test: This constructor is trivial if is_trivially_move_constructible_v<E> is true.
+#if __cpp_concepts >= 202002
+static_assert(std::is_trivially_move_constructible_v<std::expected<void, int>>);
+#endif
+static_assert(!std::is_trivially_move_constructible_v<std::expected<void, MovableNonTrivial>>);
+
+// Test: noexcept(is_nothrow_move_constructible_v<E>)
+static_assert(std::is_nothrow_move_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_move_constructible_v<std::expected<MoveMayThrow, int>>);
+static_assert(!std::is_nothrow_move_constructible_v<std::expected<int, MoveMayThrow>>);
+static_assert(!std::is_nothrow_move_constructible_v<std::expected<MoveMayThrow, MoveMayThrow>>);
+
+constexpr bool test() {
+  // move the error non-trivial
+  {
+    std::expected<void, MovableNonTrivial> e1(std::unexpect, 5);
+    auto e2 = std::move(e1);
+    assert(!e2.has_value());
+    assert(e2.error().i == 5);
+    assert(!e1.has_value());
+    assert(e1.error().i == 0);
+  }
+
+  // move the error trivial
+  {
+    std::expected<void, int> e1(std::unexpect, 5);
+    auto e2 = std::move(e1);
+    assert(!e2.has_value());
+    assert(e2.error() == 5);
+    assert(!e1.has_value());
+  }
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing() = default;
+    Throwing(Throwing&&) { throw Except{}; }
+  };
+
+  // throw on moving error
+  {
+    std::expected<void, Throwing> e1(std::unexpect);
+    try {
+      [[maybe_unused]] auto e2 = std::move(e1);
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect.pass.cpp
new file mode 100644
index 0000000000000..cdf32e68ceac3
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class... Args>
+//   constexpr explicit expected(unexpect_t, Args&&... args);
+//
+// Constraints: is_constructible_v<E, Args...> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<Args>(args)....
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <expected>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(std::is_constructible_v<std::expected<void, int>, std::unexpect_t>);
+static_assert(std::is_constructible_v<std::expected<void, int>, std::unexpect_t, int>);
+
+// !is_constructible_v<T, Args...>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<void, foo>, std::unexpect_t, int>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+static_assert(ImplicitlyConstructible<int, int>);
+
+static_assert(!ImplicitlyConstructible<std::expected<void, int>, std::unexpect_t>);
+static_assert(!ImplicitlyConstructible<std::expected<void, int>, std::unexpect_t, int>);
+
+struct CopyOnly {
+  int i;
+  constexpr CopyOnly(int ii) : i(ii) {}
+  CopyOnly(const CopyOnly&) = default;
+  CopyOnly(CopyOnly&&)      = delete;
+  friend constexpr bool operator==(const CopyOnly& mi, int ii) { return mi.i == ii; }
+};
+
+template <class T>
+constexpr void testInt() {
+  std::expected<void, T> e(std::unexpect, 5);
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+template <class T>
+constexpr void testLValue() {
+  T t(5);
+  std::expected<void, T> e(std::unexpect, t);
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+template <class T>
+constexpr void testRValue() {
+  std::expected<void, T> e(std::unexpect, T(5));
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+constexpr bool test() {
+  testInt<int>();
+  testInt<CopyOnly>();
+  testInt<MoveOnly>();
+  testLValue<int>();
+  testLValue<CopyOnly>();
+  testRValue<int>();
+  testRValue<MoveOnly>();
+
+  // no arg
+  {
+    std::expected<void, int> e(std::unexpect);
+    assert(!e.has_value());
+    assert(e.error() == 0);
+  }
+
+  // one arg
+  {
+    std::expected<void, int> e(std::unexpect, 5);
+    assert(!e.has_value());
+    assert(e.error() == 5);
+  }
+
+  // multi args
+  {
+    std::expected<void, std::tuple<int, short, MoveOnly>> e(std::unexpect, 1, 2, MoveOnly(3));
+    assert(!e.has_value());
+    assert((e.error() == std::tuple<int, short, MoveOnly>(1, 2, MoveOnly(3))));
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<void, Throwing> u(std::unexpect, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect_init_list.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect_init_list.pass.cpp
new file mode 100644
index 0000000000000..4115eadc696a2
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpect_init_list.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// template<class U, class... Args>
+//   constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
+//
+// Constraints: is_constructible_v<E, initializer_list<U>&, Args...> is true.
+//
+// Effects: Direct-non-list-initializes unex with il, std::forward<Args>(args)....
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <algorithm>
+#include <cassert>
+#include <expected>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints:
+static_assert(
+    std::is_constructible_v<std::expected<void, std::vector<int>>, std::unexpect_t, std::initializer_list<int>>);
+
+// !is_constructible_v<T, initializer_list<U>&, Args...>
+static_assert(!std::is_constructible_v<std::expected<void, int>, std::unexpect_t, std::initializer_list<int>>);
+
+// test explicit
+template <class T>
+void conversion_test(T);
+
+template <class T, class... Args>
+concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
+static_assert(ImplicitlyConstructible<int, int>);
+
+static_assert(
+    !ImplicitlyConstructible<std::expected<void, std::vector<int>>, std::unexpect_t, std::initializer_list<int>>);
+
+template <class... Ts>
+struct Data {
+  std::vector<int> vec_;
+  std::tuple<Ts...> tuple_;
+
+  template <class... Us>
+  constexpr Data(std::initializer_list<int> il, Us&&... us) : vec_(il), tuple_(std::forward<Us>(us)...) {}
+};
+
+constexpr bool test() {
+  // no arg
+  {
+    std::expected<void, Data<>> e(std::unexpect, {1, 2, 3});
+    assert(!e.has_value());
+    auto expectedList = {1, 2, 3};
+    assert(std::ranges::equal(e.error().vec_, expectedList));
+  }
+
+  // one arg
+  {
+    std::expected<void, Data<MoveOnly>> e(std::unexpect, {4, 5, 6}, MoveOnly(5));
+    assert(!e.has_value());
+    auto expectedList = {4, 5, 6};
+    assert((std::ranges::equal(e.error().vec_, expectedList)));
+    assert(std::get<0>(e.error().tuple_) == 5);
+  }
+
+  // multi args
+  {
+    int i = 5;
+    int j = 6;
+    MoveOnly m(7);
+    std::expected<void, Data<int&, int&&, MoveOnly>> e(std::unexpect, {1, 2}, i, std::move(j), std::move(m));
+    assert(!e.has_value());
+    auto expectedList = {1, 2};
+    assert((std::ranges::equal(e.error().vec_, expectedList)));
+    assert(&std::get<0>(e.error().tuple_) == &i);
+    assert(&std::get<1>(e.error().tuple_) == &j);
+    assert(std::get<2>(e.error().tuple_) == 7);
+    assert(m.get() == 0);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(std::initializer_list<int>, int) { throw Except{}; };
+  };
+
+  try {
+    std::expected<void, Throwing> u(std::unexpect, {1, 2}, 5);
+    assert(false);
+  } catch (Except) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.copy.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.copy.pass.cpp
new file mode 100644
index 0000000000000..89e1c9275e3e0
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.copy.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class G>
+//   constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
+//
+// Let GF be const G&
+//
+// Constraints: is_constructible_v<E, GF> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<GF>(e.error()).
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints
+static_assert(std::is_constructible_v<std::expected<void, int>, const std::unexpected<int>&>);
+
+// !is_constructible_v<E, GF>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<void, int>, const std::unexpected<foo>&>);
+static_assert(!std::is_constructible_v<std::expected<void, MoveOnly>, const std::unexpected<MoveOnly>&>);
+
+// explicit(!is_convertible_v<const G&, E>)
+struct NotConvertible {
+  explicit NotConvertible(int);
+};
+static_assert(std::is_convertible_v<const std::unexpected<int>&, std::expected<void, int>>);
+static_assert(!std::is_convertible_v<const std::unexpected<int>&, std::expected<void, NotConvertible>>);
+
+struct MyInt {
+  int i;
+  constexpr MyInt(int ii) : i(ii) {}
+  friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
+};
+
+template <class T>
+constexpr void testUnexpected() {
+  const std::unexpected<int> u(5);
+  std::expected<void, T> e(u);
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+constexpr bool test() {
+  testUnexpected<int>();
+  testUnexpected<MyInt>();
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; }
+  };
+
+  {
+    const std::unexpected<int> u(5);
+    try {
+      [[maybe_unused]] std::expected<void, Throwing> e(u);
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.move.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.move.pass.cpp
new file mode 100644
index 0000000000000..2ddcb63c085f0
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.move.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class G>
+//   constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
+//
+// Let GF be G
+//
+// Constraints: is_constructible_v<E, GF> is true.
+//
+// Effects: Direct-non-list-initializes unex with std::forward<GF>(e.error()).
+//
+// Postconditions: has_value() is false.
+//
+// Throws: Any exception thrown by the initialization of unex.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+// Test Constraints
+static_assert(std::is_constructible_v<std::expected<void, int>, std::unexpected<int>>);
+static_assert(std::is_constructible_v<std::expected<void, MoveOnly>, std::unexpected<MoveOnly>>);
+
+// !is_constructible_v<E, GF>
+struct foo {};
+static_assert(!std::is_constructible_v<std::expected<void, int>, std::unexpected<foo>>);
+
+// explicit(!is_convertible_v<G, E>)
+struct NotConvertible {
+  explicit NotConvertible(int);
+};
+static_assert(std::is_convertible_v<std::unexpected<int>&&, std::expected<void, int>>);
+static_assert(!std::is_convertible_v<std::unexpected<int>&&, std::expected<void, NotConvertible>>);
+
+struct MyInt {
+  int i;
+  constexpr MyInt(int ii) : i(ii) {}
+  friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
+};
+
+template <class Err>
+constexpr void testInt() {
+  std::unexpected<int> u(5);
+  std::expected<void, Err> e(std::move(u));
+  assert(!e.has_value());
+  assert(e.error() == 5);
+}
+
+constexpr void testMoveOnly() {
+  std::unexpected<MoveOnly> u(MoveOnly(5));
+  std::expected<void, MoveOnly> e(std::move(u));
+  assert(!e.has_value());
+  assert(e.error() == 5);
+  assert(u.error() == 0);
+}
+
+constexpr bool test() {
+  testInt<int>();
+  testInt<MyInt>();
+  testInt<MoveOnly>();
+  testMoveOnly();
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  struct Except {};
+
+  struct Throwing {
+    Throwing(int) { throw Except{}; }
+  };
+
+  {
+    std::unexpected<int> u(5);
+    try {
+      [[maybe_unused]] std::expected<void, Throwing> e(std::move(u));
+      assert(false);
+    } catch (Except) {
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/dtor.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/dtor.pass.cpp
new file mode 100644
index 0000000000000..855d585756317
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/dtor.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr ~expected();
+//
+// Effects: If has_value() is false, destroys unex.
+//
+// Remarks: If is_trivially_destructible_v<E> is true, then this destructor is a trivial destructor.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test Remarks: If is_trivially_destructible_v<E> is true, then this destructor is a trivial destructor.
+struct NonTrivial {
+  ~NonTrivial() {}
+};
+
+#if __cpp_concepts >= 202002
+static_assert(std::is_trivially_destructible_v<std::expected<void, int>>);
+#endif
+static_assert(!std::is_trivially_destructible_v<std::expected<void, NonTrivial>>);
+
+struct TrackedDestroy {
+  bool& destroyed;
+  constexpr TrackedDestroy(bool& b) : destroyed(b) {}
+  constexpr ~TrackedDestroy() { destroyed = true; }
+};
+
+constexpr bool test() {
+  // has value
+  { [[maybe_unused]] std::expected<void, TrackedDestroy> e(std::in_place); }
+
+  // has error
+  {
+    bool errorDestroyed = false;
+    { [[maybe_unused]] std::expected<void, TrackedDestroy> e(std::unexpect, errorDestroyed); }
+    assert(errorDestroyed);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp
new file mode 100644
index 0000000000000..eb05a84643211
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class T2, class E2> requires (is_void_v<T2>)
+//   friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test constraint
+template <class T1, class T2>
+concept CanCompare = requires(T1 t1, T2 t2) { t1 == t2; };
+
+struct Foo{};
+static_assert(!CanCompare<Foo, Foo>);
+
+static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
+static_assert(CanCompare<std::expected<void, int>, std::expected<void, short>>);
+
+// Note this is true because other overloads in expected<non-void> are unconstrained
+static_assert(CanCompare<std::expected<void, int>, std::expected<int, int>>);
+
+constexpr bool test() {
+  // x.has_value() && y.has_value()
+  {
+    const std::expected<void, int> e1;
+    const std::expected<void, int> e2;
+    assert(e1 == e2);
+  }
+
+  // !x.has_value() && y.has_value()
+  {
+    const std::expected<void, int> e1(std::unexpect, 5);
+    const std::expected<void, int> e2;
+    assert(e1 != e2);
+  }
+
+  // x.has_value() && !y.has_value()
+  {
+    const std::expected<void, int> e1;
+    const std::expected<void, int> e2(std::unexpect, 10);
+    const std::expected<void, int> e3(std::unexpect, 5);
+    assert(e1 != e2);
+    assert(e1 != e3);
+  }
+
+  // !x.has_value() && !y.has_value()
+  {
+    const std::expected<void, int> e1(std::unexpect, 5);
+    const std::expected<void, int> e2(std::unexpect, 10);
+    const std::expected<void, int> e3(std::unexpect, 5);
+    assert(e1 != e2);
+    assert(e1 == e3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp
new file mode 100644
index 0000000000000..ce95d162b55b1
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Data {
+  int i;
+  constexpr Data(int ii) : i(ii) {}
+
+  friend constexpr bool operator==(const Data& data, int ii) { return data.i == ii; }
+};
+
+constexpr bool test() {
+  // x.has_value()
+  {
+    const std::expected<void, Data> e1;
+    std::unexpected<int> un2(10);
+    std::unexpected<int> un3(5);
+    assert(e1 != un2);
+    assert(e1 != un3);
+  }
+
+  // !x.has_value()
+  {
+    const std::expected<void, Data> e1(std::unexpect, 5);
+    std::unexpected<int> un2(10);
+    std::unexpected<int> un3(5);
+    assert(e1 != un2);
+    assert(e1 == un3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/observers/bool.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/observers/bool.pass.cpp
new file mode 100644
index 0000000000000..42e9f22969663
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/observers/bool.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr explicit operator bool() const noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept OpBoolNoexcept =
+    requires(T t) {
+      { static_cast<bool>(t) } noexcept;
+    };
+
+struct Foo {};
+static_assert(!OpBoolNoexcept<Foo>);
+
+static_assert(OpBoolNoexcept<std::expected<void, int>>);
+static_assert(OpBoolNoexcept<const std::expected<void, int>>);
+
+// Test explicit
+static_assert(!std::is_convertible_v<std::expected<void, int>, bool>);
+
+constexpr bool test() {
+  // has_value
+  {
+    const std::expected<void, int> e;
+    assert(static_cast<bool>(e));
+  }
+
+  // !has_value
+  {
+    const std::expected<void, int> e(std::unexpect, 5);
+    assert(!static_cast<bool>(e));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/observers/deref.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/observers/deref.pass.cpp
new file mode 100644
index 0000000000000..536f8980c27a4
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/observers/deref.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr void operator*() const & noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept DerefNoexcept =
+    requires(T t) {
+      { std::forward<T>(t).operator*() } noexcept;
+    };
+
+static_assert(!DerefNoexcept<int>);
+
+static_assert(DerefNoexcept<std::expected<void, int>>);
+
+constexpr bool test() {
+  const std::expected<void, int> e;
+  *e;
+  static_assert(std::is_same_v<decltype(*e), void>);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/observers/error.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/observers/error.pass.cpp
new file mode 100644
index 0000000000000..f7be7607aede3
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/observers/error.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr const E& error() const & noexcept;
+// constexpr E& error() & noexcept;
+// constexpr E&& error() && noexcept;
+// constexpr const E&& error() const && noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept ErrorNoexcept =
+    requires(T t) {
+      { std::forward<T>(t).error() } noexcept;
+    };
+
+static_assert(!ErrorNoexcept<int>);
+
+static_assert(ErrorNoexcept<std::expected<void, int>&>);
+static_assert(ErrorNoexcept<const std::expected<void, int>&>);
+static_assert(ErrorNoexcept<std::expected<void, int>&&>);
+static_assert(ErrorNoexcept<const std::expected<void, int>&&>);
+
+constexpr bool test() {
+  // non-const &
+  {
+    std::expected<void, int> e(std::unexpect, 5);
+    decltype(auto) x = e.error();
+    static_assert(std::same_as<decltype(x), int&>);
+    assert(x == 5);
+  }
+
+  // const &
+  {
+    const std::expected<void, int> e(std::unexpect, 5);
+    decltype(auto) x = e.error();
+    static_assert(std::same_as<decltype(x), const int&>);
+    assert(x == 5);
+  }
+
+  // non-const &&
+  {
+    std::expected<void, int> e(std::unexpect, 5);
+    decltype(auto) x = std::move(e).error();
+    static_assert(std::same_as<decltype(x), int&&>);
+    assert(x == 5);
+  }
+
+  // const &&
+  {
+    const std::expected<void, int> e(std::unexpect, 5);
+    decltype(auto) x = std::move(e).error();
+    static_assert(std::same_as<decltype(x), const int&&>);
+    assert(x == 5);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/observers/has_value.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/observers/has_value.pass.cpp
new file mode 100644
index 0000000000000..42a173d60c898
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/observers/has_value.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr bool has_value() const noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+// Test noexcept
+template <class T>
+concept HasValueNoexcept =
+    requires(T t) {
+      { t.has_value() } noexcept;
+    };
+
+struct Foo {};
+static_assert(!HasValueNoexcept<Foo>);
+
+static_assert(HasValueNoexcept<std::expected<int, int>>);
+static_assert(HasValueNoexcept<const std::expected<int, int>>);
+
+constexpr bool test() {
+  // has_value
+  {
+    const std::expected<void, int> e;
+    assert(e.has_value());
+  }
+
+  // !has_value
+  {
+    const std::expected<void, int> e(std::unexpect, 5);
+    assert(!e.has_value());
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/observers/value.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/observers/value.pass.cpp
new file mode 100644
index 0000000000000..0f02db19c7b75
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/observers/value.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr void value() const &;
+// constexpr void value() &&;
+
+#include <cassert>
+#include <concepts>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+#include "test_macros.h"
+
+constexpr bool test() {
+  // const &
+  {
+    const std::expected<void, int> e;
+    e.value();
+    static_assert(std::is_same_v<decltype(e.value()), void>);
+  }
+
+  // &
+  {
+    std::expected<void, int> e;
+    e.value();
+    static_assert(std::is_same_v<decltype(e.value()), void>);
+  }
+
+  // &&
+  {
+    std::expected<void, int> e;
+    std::move(e).value();
+    static_assert(std::is_same_v<decltype(std::move(e).value()), void>);
+  }
+
+  // const &&
+  {
+    const std::expected<void, int> e;
+    std::move(e).value();
+    static_assert(std::is_same_v<decltype(std::move(e).value()), void>);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+  // int
+  {
+    const std::expected<void, int> e(std::unexpect, 5);
+    try {
+      e.value();
+      assert(false);
+    } catch (const std::bad_expected_access<int>& ex) {
+      assert(ex.error() == 5);
+    }
+  }
+
+  // MoveOnly
+  {
+    std::expected<void, MoveOnly> e(std::unexpect, 5);
+    try {
+      std::move(e).value();
+      assert(false);
+    } catch (const std::bad_expected_access<MoveOnly>& ex) {
+      assert(ex.error() == 5);
+    }
+  }
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/swap/free.swap.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/swap/free.swap.pass.cpp
new file mode 100644
index 0000000000000..0f5821ec4ad69
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/swap/free.swap.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, clang-15, apple-clang-14
+
+// friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(swap(x,y)));
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+// Test constraint
+static_assert(std::is_swappable_v<std::expected<void, int>>);
+
+struct NotSwappable {
+  NotSwappable& operator=(const NotSwappable&) = delete;
+};
+void swap(NotSwappable&, NotSwappable&) = delete;
+
+// !is_swappable_v<E>
+static_assert(!std::is_swappable_v<std::expected<void, NotSwappable>>);
+
+struct NotMoveContructible {
+  NotMoveContructible(NotMoveContructible&&) = delete;
+  friend void swap(NotMoveContructible&, NotMoveContructible&) {}
+};
+
+// !is_move_constructible_v<E>
+static_assert(!std::is_swappable_v<std::expected<void, NotMoveContructible>>);
+
+// Test noexcept
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow&&) noexcept(false);
+  friend void swap(MoveMayThrow&, MoveMayThrow&) noexcept {}
+};
+
+template <class E>
+concept FreeSwapNoexcept =
+    requires(std::expected<void, E> x, std::expected<void, E> y) {
+      { swap(x, y) } noexcept;
+    };
+
+static_assert(FreeSwapNoexcept<int>);
+
+// !is_nothrow_move_constructible_v<E>
+static_assert(!FreeSwapNoexcept<MoveMayThrow>);
+
+struct SwapMayThrow {
+  friend void swap(SwapMayThrow&, SwapMayThrow&) noexcept(false) {}
+};
+
+// !is_nothrow_swappable_v<E>
+static_assert(!FreeSwapNoexcept<SwapMayThrow>);
+
+constexpr bool test() {
+  // this->has_value() && rhs.has_value()
+  {
+    std::expected<void, int> x;
+    std::expected<void, int> y;
+    swap(x, y);
+
+    assert(x.has_value());
+    assert(y.has_value());
+  }
+
+  // !this->has_value() && !rhs.has_value()
+  {
+    std::expected<void, ADLSwap> x(std::unexpect, 5);
+    std::expected<void, ADLSwap> y(std::unexpect, 10);
+    swap(x, y);
+
+    assert(!x.has_value());
+    assert(x.error().i == 10);
+    assert(x.error().adlSwapCalled);
+    assert(!y.has_value());
+    assert(y.error().i == 5);
+    assert(y.error().adlSwapCalled);
+  }
+
+  // this->has_value() && !rhs.has_value()
+  {
+    Traced::state s{};
+    std::expected<void, Traced> e1(std::in_place);
+    std::expected<void, Traced> e2(std::unexpect, s, 10);
+
+    e1.swap(e2);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(e2.has_value());
+
+    assert(s.moveCtorCalled);
+    assert(s.dtorCalled);
+  }
+
+  // !this->has_value() && rhs.has_value()
+  {
+    Traced::state s{};
+    std::expected<void, Traced> e1(std::unexpect, s, 10);
+    std::expected<void, Traced> e2(std::in_place);
+
+    e1.swap(e2);
+
+    assert(e1.has_value());
+    assert(!e2.has_value());
+    assert(e2.error().data_ == 10);
+
+    assert(s.moveCtorCalled);
+    assert(s.dtorCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  // !e1.has_value() && e2.has_value()
+  {
+    bool e1Destroyed = false;
+    std::expected<void, ThrowOnMove> e1(std::unexpect, e1Destroyed);
+    std::expected<void, ThrowOnMove> e2(std::in_place);
+    try {
+      swap(e1, e2);
+      assert(false);
+    } catch (Except) {
+      assert(!e1.has_value());
+      assert(e2.has_value());
+      assert(!e1Destroyed);
+    }
+  }
+
+  // e1.has_value() && !e2.has_value()
+  {
+    bool e2Destroyed = false;
+    std::expected<void, ThrowOnMove> e1(std::in_place);
+    std::expected<void, ThrowOnMove> e2(std::unexpect, e2Destroyed);
+    try {
+      swap(e1, e2);
+      assert(false);
+    } catch (Except) {
+      assert(e1.has_value());
+      assert(!e2.has_value());
+      assert(!e2Destroyed);
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.void/swap/member.swap.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/swap/member.swap.pass.cpp
new file mode 100644
index 0000000000000..247d92a51dc0c
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.void/swap/member.swap.pass.cpp
@@ -0,0 +1,173 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// Older Clangs do not support the C++20 feature to constrain destructors
+// XFAIL: clang-14, apple-clang-14
+
+// constexpr void swap(expected& rhs) noexcept(see below);
+//
+// Constraints:
+// is_swappable_v<E> is true and is_move_constructible_v<E> is true.
+//
+// Throws: Any exception thrown by the expressions in the Effects.
+//
+// Remarks: The exception specification is equivalent to:
+// is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>.
+
+#include <cassert>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../../types.h"
+#include "test_macros.h"
+
+// Test Constraints:
+template <class E>
+concept HasMemberSwap = requires(std::expected<void, E> x, std::expected<void, E> y) { x.swap(y); };
+
+static_assert(HasMemberSwap<int>);
+
+struct NotSwappable {};
+void swap(NotSwappable&, NotSwappable&) = delete;
+
+// !is_swappable_v<E>
+static_assert(!HasMemberSwap<NotSwappable>);
+
+struct NotMoveContructible {
+  NotMoveContructible(NotMoveContructible&&) = delete;
+  friend void swap(NotMoveContructible&, NotMoveContructible&) {}
+};
+
+// !is_move_constructible_v<E>
+static_assert(!HasMemberSwap<NotMoveContructible>);
+
+// Test noexcept
+struct MoveMayThrow {
+  MoveMayThrow(MoveMayThrow&&) noexcept(false);
+  friend void swap(MoveMayThrow&, MoveMayThrow&) noexcept {}
+};
+
+template <class E>
+concept MemberSwapNoexcept =
+    requires(std::expected<void, E> x, std::expected<void, E> y) {
+      { x.swap(y) } noexcept;
+    };
+
+static_assert(MemberSwapNoexcept<int>);
+
+// !is_nothrow_move_constructible_v<E>
+static_assert(!MemberSwapNoexcept<MoveMayThrow>);
+
+struct SwapMayThrow {
+  friend void swap(SwapMayThrow&, SwapMayThrow&) noexcept(false) {}
+};
+
+// !is_nothrow_swappable_v<E>
+static_assert(!MemberSwapNoexcept<SwapMayThrow>);
+
+constexpr bool test() {
+  // this->has_value() && rhs.has_value()
+  {
+    std::expected<void, int> x;
+    std::expected<void, int> y;
+    x.swap(y);
+
+    assert(x.has_value());
+    assert(y.has_value());
+  }
+
+  // !this->has_value() && !rhs.has_value()
+  {
+    std::expected<void, ADLSwap> x(std::unexpect, 5);
+    std::expected<void, ADLSwap> y(std::unexpect, 10);
+    x.swap(y);
+
+    assert(!x.has_value());
+    assert(x.error().i == 10);
+    assert(x.error().adlSwapCalled);
+    assert(!y.has_value());
+    assert(y.error().i == 5);
+    assert(y.error().adlSwapCalled);
+  }
+
+  // this->has_value() && !rhs.has_value()
+  {
+    Traced::state s{};
+    std::expected<void, Traced> e1(std::in_place);
+    std::expected<void, Traced> e2(std::unexpect, s, 10);
+
+    e1.swap(e2);
+
+    assert(!e1.has_value());
+    assert(e1.error().data_ == 10);
+    assert(e2.has_value());
+
+    assert(s.moveCtorCalled);
+    assert(s.dtorCalled);
+  }
+
+  // !this->has_value() && rhs.has_value()
+  {
+    Traced::state s{};
+    std::expected<void, Traced> e1(std::unexpect, s, 10);
+    std::expected<void, Traced> e2(std::in_place);
+
+    e1.swap(e2);
+
+    assert(e1.has_value());
+    assert(!e2.has_value());
+    assert(e2.error().data_ == 10);
+
+    assert(s.moveCtorCalled);
+    assert(s.dtorCalled);
+  }
+
+  return true;
+}
+
+void testException() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  // !e1.has_value() && e2.has_value()
+  {
+    bool e1Destroyed = false;
+    std::expected<void, ThrowOnMove> e1(std::unexpect, e1Destroyed);
+    std::expected<void, ThrowOnMove> e2(std::in_place);
+    try {
+      e1.swap(e2);
+      assert(false);
+    } catch (Except) {
+      assert(!e1.has_value());
+      assert(e2.has_value());
+      assert(!e1Destroyed);
+    }
+  }
+
+  // e1.has_value() && !e2.has_value()
+  {
+    bool e2Destroyed = false;
+    std::expected<void, ThrowOnMove> e1(std::in_place);
+    std::expected<void, ThrowOnMove> e2(std::unexpect, e2Destroyed);
+    try {
+      e1.swap(e2);
+      assert(false);
+    } catch (Except) {
+      assert(e1.has_value());
+      assert(!e2.has_value());
+      assert(!e2Destroyed);
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  testException();
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/types.h b/libcxx/test/std/utilities/expected/types.h
new file mode 100644
index 0000000000000..278ab0f0ec746
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/types.h
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_UTILITIES_EXPECTED_TYPES_H
+#define TEST_STD_UTILITIES_EXPECTED_TYPES_H
+
+#include <utility>
+#include "test_macros.h"
+
+template <bool copyMoveNoexcept, bool convertNoexcept = true>
+struct TracedBase {
+  struct state {
+    bool copyCtorCalled   = false;
+    bool copyAssignCalled = false;
+    bool moveCtorCalled   = false;
+    bool moveAssignCalled = false;
+    bool dtorCalled       = false;
+  };
+
+  state* state_      = nullptr;
+  bool copiedFromInt = false;
+  bool movedFromInt  = false;
+  bool copiedFromTmp = false;
+  bool movedFromTmp  = false;
+  int data_;
+
+  constexpr TracedBase(const int& ii) noexcept(convertNoexcept) : data_(ii) { copiedFromInt = true; }
+  constexpr TracedBase(int&& ii) noexcept(convertNoexcept) : data_(ii) { movedFromInt = true; }
+  constexpr TracedBase(state& s, int ii) noexcept : state_(&s), data_(ii) {}
+  constexpr TracedBase(const TracedBase& other) noexcept(copyMoveNoexcept) : state_(other.state_), data_(other.data_) {
+    if (state_) {
+      state_->copyCtorCalled = true;
+    } else {
+      copiedFromTmp = true;
+    }
+  }
+  constexpr TracedBase(TracedBase&& other) noexcept(copyMoveNoexcept) : state_(other.state_), data_(other.data_) {
+    if (state_) {
+      state_->moveCtorCalled = true;
+    } else {
+      movedFromTmp = true;
+    }
+  }
+  constexpr TracedBase& operator=(const TracedBase& other) noexcept(copyMoveNoexcept) {
+    data_                    = other.data_;
+    state_->copyAssignCalled = true;
+    return *this;
+  }
+  constexpr TracedBase& operator=(TracedBase&& other) noexcept(copyMoveNoexcept) {
+    data_                    = other.data_;
+    state_->moveAssignCalled = true;
+    return *this;
+  }
+  constexpr ~TracedBase() {
+    if (state_) {
+      state_->dtorCalled = true;
+    }
+  }
+};
+
+using Traced         = TracedBase<false>;
+using TracedNoexcept = TracedBase<true>;
+
+using MoveThrowConvNoexcept = TracedBase<false, true>;
+using MoveNoexceptConvThrow = TracedBase<true, false>;
+using BothMayThrow          = TracedBase<false, false>;
+using BothNoexcept          = TracedBase<true, true>;
+
+struct ADLSwap {
+  int i;
+  bool adlSwapCalled = false;
+  constexpr ADLSwap(int ii) : i(ii) {}
+  constexpr friend void swap(ADLSwap& x, ADLSwap& y) {
+    std::swap(x.i, y.i);
+    x.adlSwapCalled = true;
+    y.adlSwapCalled = true;
+  }
+};
+
+template <bool Noexcept>
+struct TrackedMove {
+  int i;
+  int numberOfMoves = 0;
+  bool swapCalled   = false;
+
+  constexpr TrackedMove(int ii) : i(ii) {}
+  constexpr TrackedMove(TrackedMove&& other) noexcept(Noexcept)
+      : i(other.i), numberOfMoves(other.numberOfMoves), swapCalled(other.swapCalled) {
+    ++numberOfMoves;
+  }
+
+  constexpr friend void swap(TrackedMove& x, TrackedMove& y) {
+    std::swap(x.i, y.i);
+    std::swap(x.numberOfMoves, y.numberOfMoves);
+    x.swapCalled = true;
+    y.swapCalled = true;
+  }
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct Except {};
+
+struct ThrowOnCopyConstruct {
+  ThrowOnCopyConstruct() = default;
+  ThrowOnCopyConstruct(const ThrowOnCopyConstruct&) { throw Except{}; }
+  ThrowOnCopyConstruct& operator=(const ThrowOnCopyConstruct&) = default;
+};
+
+struct ThrowOnMoveConstruct {
+  ThrowOnMoveConstruct() = default;
+  ThrowOnMoveConstruct(ThrowOnMoveConstruct&&) { throw Except{}; }
+  ThrowOnMoveConstruct& operator=(ThrowOnMoveConstruct&&) = default;
+};
+
+struct ThrowOnConvert {
+  ThrowOnConvert() = default;
+  ThrowOnConvert(const int&) { throw Except{}; }
+  ThrowOnConvert(int&&) { throw Except{}; }
+  ThrowOnConvert(const ThrowOnConvert&) noexcept(false) {}
+  ThrowOnConvert& operator=(const ThrowOnConvert&) = default;
+  ThrowOnConvert(ThrowOnConvert&&) noexcept(false) {}
+  ThrowOnConvert& operator=(ThrowOnConvert&&) = default;
+};
+
+struct ThrowOnMove {
+  bool* destroyed = nullptr;
+  ThrowOnMove()   = default;
+  ThrowOnMove(bool& d) : destroyed(&d) {}
+  ThrowOnMove(ThrowOnMove&&) { throw Except{}; };
+  ThrowOnMove& operator=(ThrowOnMove&&) = default;
+  ~ThrowOnMove() {
+    if (destroyed) {
+      *destroyed = true;
+    }
+  }
+};
+
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+#endif // TEST_STD_UTILITIES_EXPECTED_TYPES_H

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 81086993a5f49..891981d45b8d6 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -308,6 +308,10 @@ def add_version_header(tc):
     "values": { "c++17": 201603, "c++20": 201902 },
     "headers": ["execution"],
     "unimplemented": True,
+  }, {
+    "name": "__cpp_lib_expected",
+    "values": { "c++2b": 202202 },
+    "headers": ["expected"],
   }, {
     "name": "__cpp_lib_filesystem",
     "values": { "c++17": 201703 },

diff  --git a/libcxx/utils/generate_header_inclusion_tests.py b/libcxx/utils/generate_header_inclusion_tests.py
index 6019abeb7f365..e96551d1f7ad3 100755
--- a/libcxx/utils/generate_header_inclusion_tests.py
+++ b/libcxx/utils/generate_header_inclusion_tests.py
@@ -68,6 +68,7 @@ def get_libcxx_paths():
     "concepts": "20",
     "coroutine": "20",
     "cuchar": "11",
+    "expected": "23",
     "filesystem": "17",
     "initializer_list": "11",
     "optional": "17",


        


More information about the libcxx-commits mailing list