From cfadbcd950d4845b21ea540f7a586e56442efbf8 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Mon, 10 Jul 2023 17:30:11 +0200 Subject: [PATCH] AK: Work around Xcode 15 beta mishandling trailing `requires` clauses Xcode 15 betas 1-3 lack https://reviews.llvm.org/D135772, which fixes a bug that causes trailing `requires` clauses to be evaluated twice, failing the second time. Reported as FB12284201. This caused compile errors when instantiating types derived from RefPtr: > error: invalid reference to function 'NonnullRefPtr': constraints not > satisfied > note: because substituted constraint expression is ill-formed: value > of type '' is not contextually convertible to 'bool'. This commit works around the issue by moving the `requires` clauses after the template parameter list. In most cases, trailing `requires` clauses and those specified after the template parameter list work identically, so this change should not impact the code's behavior. The only difference is that trailing requires clauses are evaluated *after* constrained placeholder types (i.e. `Integral auto i` function parameter). --- AK/NonnullRefPtr.h | 14 +++++++------- AK/RefPtr.h | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/AK/NonnullRefPtr.h b/AK/NonnullRefPtr.h index 468f45e84c..049181ecdc 100644 --- a/AK/NonnullRefPtr.h +++ b/AK/NonnullRefPtr.h @@ -53,8 +53,8 @@ public: } template - ALWAYS_INLINE NonnullRefPtr(U const& object) requires(IsConvertible) + ALWAYS_INLINE NonnullRefPtr(U const& object) : m_ptr(const_cast(static_cast(&object))) { m_ptr->ref(); @@ -71,8 +71,8 @@ public: } template - ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr&& other) requires(IsConvertible) + ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr&& other) : m_ptr(static_cast(&other.leak_ref())) { } @@ -84,8 +84,8 @@ public: } template - ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr const& other) requires(IsConvertible) + ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr const& other) : m_ptr(const_cast(static_cast(other.ptr()))) { m_ptr->ref(); @@ -120,8 +120,8 @@ public: } template - NonnullRefPtr& operator=(NonnullRefPtr const& other) requires(IsConvertible) + NonnullRefPtr& operator=(NonnullRefPtr const& other) { NonnullRefPtr tmp { other }; swap(tmp); @@ -136,8 +136,8 @@ public: } template - NonnullRefPtr& operator=(NonnullRefPtr&& other) requires(IsConvertible) + NonnullRefPtr& operator=(NonnullRefPtr&& other) { NonnullRefPtr tmp { move(other) }; swap(tmp); @@ -201,8 +201,8 @@ public: bool operator==(NonnullRefPtr const& other) const { return m_ptr == other.m_ptr; } template - bool operator==(RawPtr other) const requires(IsPointer) + bool operator==(RawPtr other) const { return m_ptr == other; } @@ -265,8 +265,8 @@ struct Formatter> : Formatter { }; template -inline void swap(NonnullRefPtr& a, NonnullRefPtr& b) requires(IsConvertible) +inline void swap(NonnullRefPtr& a, NonnullRefPtr& b) { a.swap(b); } diff --git a/AK/RefPtr.h b/AK/RefPtr.h index 305a1438e5..0cc650bcd1 100644 --- a/AK/RefPtr.h +++ b/AK/RefPtr.h @@ -63,23 +63,23 @@ public: } template - ALWAYS_INLINE RefPtr(NonnullRefPtr const& other) requires(IsConvertible) + ALWAYS_INLINE RefPtr(NonnullRefPtr const& other) : m_ptr(const_cast(static_cast(other.ptr()))) { m_ptr->ref(); } template - ALWAYS_INLINE RefPtr(NonnullRefPtr&& other) requires(IsConvertible) + ALWAYS_INLINE RefPtr(NonnullRefPtr&& other) : m_ptr(static_cast(&other.leak_ref())) { } template - RefPtr(RefPtr&& other) requires(IsConvertible) + RefPtr(RefPtr&& other) : m_ptr(static_cast(other.leak_ref())) { } @@ -131,8 +131,8 @@ public: } template - ALWAYS_INLINE RefPtr& operator=(RefPtr&& other) requires(IsConvertible) + ALWAYS_INLINE RefPtr& operator=(RefPtr&& other) { RefPtr tmp { move(other) }; swap(tmp); @@ -140,8 +140,8 @@ public: } template - ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr&& other) requires(IsConvertible) + ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr&& other) { RefPtr tmp { move(other) }; swap(tmp); @@ -156,8 +156,8 @@ public: } template - ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr const& other) requires(IsConvertible) + ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr const& other) { RefPtr tmp { other }; swap(tmp); @@ -172,8 +172,8 @@ public: } template - ALWAYS_INLINE RefPtr& operator=(RefPtr const& other) requires(IsConvertible) + ALWAYS_INLINE RefPtr& operator=(RefPtr const& other) { RefPtr tmp { other }; swap(tmp); @@ -261,8 +261,8 @@ public: bool operator==(NonnullRefPtr const& other) const { return as_ptr() == other.m_ptr; } template - bool operator==(RawPtr other) const requires(IsPointer) + bool operator==(RawPtr other) const { return as_ptr() == other; } @@ -313,8 +313,8 @@ inline RefPtr static_ptr_cast(RefPtr const& ptr) } template -inline void swap(RefPtr& a, RefPtr& b) requires(IsConvertible) +inline void swap(RefPtr& a, RefPtr& b) { a.swap(b); }