https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120088
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2025-05-06 Ever confirmed|0 |1 Keywords| |rejects-valid Status|UNCONFIRMED |NEW --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- The libstdc++ implementation can be reduced to the following, which is rejected the same way: #include <memory> struct unexpected { }; template<typename T, typename E> struct expected { constexpr expected(unexpected) noexcept : m_unex(), m_has_value(false) { } constexpr expected() noexcept : m_void(), m_has_value(true) { } expected(const expected&) = default; constexpr ~expected() = default; expected& operator=(const expected&) = delete; constexpr expected& operator=(const expected& x) requires true { if (x.m_has_value) emplace(); else m_assign_unex(x.m_unex); return *this; } constexpr void emplace() { if (!m_has_value) { std::destroy_at(&m_unex); m_has_value = true; } } constexpr void m_assign_unex(const E& v) { if (m_has_value) { std::construct_at(&m_unex, v); m_has_value = false; } else m_unex = v; } union { struct { } m_void; E m_unex; }; bool m_has_value; }; constexpr bool quux() { expected<void, int> foo1{unexpected{}}; expected<void, int> foo2{}; foo1 = foo2; [[maybe_unused]] expected<void, int> foo3{foo1}; return true; } static_assert(quux()); I'm not sure what needs to be changed here.