Pārlūkot izejas kodu

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 '<dependent 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).
Daniel Bertalan 2 gadi atpakaļ
vecāks
revīzija
cfadbcd950
2 mainītis faili ar 16 papildinājumiem un 16 dzēšanām
  1. 7 7
      AK/NonnullRefPtr.h
  2. 9 9
      AK/RefPtr.h

+ 7 - 7
AK/NonnullRefPtr.h

@@ -53,8 +53,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE NonnullRefPtr(U const& object)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE NonnullRefPtr(U const& object)
         : m_ptr(const_cast<T*>(static_cast<T const*>(&object)))
     {
         m_ptr->ref();
@@ -71,8 +71,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr<U>&& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr<U>&& other)
         : m_ptr(static_cast<T*>(&other.leak_ref()))
     {
     }
@@ -84,8 +84,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr<U> const& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE NonnullRefPtr(NonnullRefPtr<U> const& other)
         : m_ptr(const_cast<T*>(static_cast<T const*>(other.ptr())))
     {
         m_ptr->ref();
@@ -120,8 +120,8 @@ public:
     }
 
     template<typename U>
-    NonnullRefPtr& operator=(NonnullRefPtr<U> const& other)
     requires(IsConvertible<U*, T*>)
+    NonnullRefPtr& operator=(NonnullRefPtr<U> const& other)
     {
         NonnullRefPtr tmp { other };
         swap(tmp);
@@ -136,8 +136,8 @@ public:
     }
 
     template<typename U>
-    NonnullRefPtr& operator=(NonnullRefPtr<U>&& other)
     requires(IsConvertible<U*, T*>)
+    NonnullRefPtr& operator=(NonnullRefPtr<U>&& 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<typename RawPtr>
-    bool operator==(RawPtr other) const
     requires(IsPointer<RawPtr>)
+    bool operator==(RawPtr other) const
     {
         return m_ptr == other;
     }
@@ -265,8 +265,8 @@ struct Formatter<NonnullRefPtr<T>> : Formatter<T const*> {
 };
 
 template<typename T, typename U>
-inline void swap(NonnullRefPtr<T>& a, NonnullRefPtr<U>& b)
 requires(IsConvertible<U*, T*>)
+inline void swap(NonnullRefPtr<T>& a, NonnullRefPtr<U>& b)
 {
     a.swap(b);
 }

+ 9 - 9
AK/RefPtr.h

@@ -63,23 +63,23 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE RefPtr(NonnullRefPtr<U> const& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE RefPtr(NonnullRefPtr<U> const& other)
         : m_ptr(const_cast<T*>(static_cast<T const*>(other.ptr())))
     {
         m_ptr->ref();
     }
 
     template<typename U>
-    ALWAYS_INLINE RefPtr(NonnullRefPtr<U>&& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE RefPtr(NonnullRefPtr<U>&& other)
         : m_ptr(static_cast<T*>(&other.leak_ref()))
     {
     }
 
     template<typename U>
-    RefPtr(RefPtr<U>&& other)
     requires(IsConvertible<U*, T*>)
+    RefPtr(RefPtr<U>&& other)
         : m_ptr(static_cast<T*>(other.leak_ref()))
     {
     }
@@ -131,8 +131,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE RefPtr& operator=(RefPtr<U>&& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE RefPtr& operator=(RefPtr<U>&& other)
     {
         RefPtr tmp { move(other) };
         swap(tmp);
@@ -140,8 +140,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr<U>&& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr<U>&& other)
     {
         RefPtr tmp { move(other) };
         swap(tmp);
@@ -156,8 +156,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr<U> const& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE RefPtr& operator=(NonnullRefPtr<U> const& other)
     {
         RefPtr tmp { other };
         swap(tmp);
@@ -172,8 +172,8 @@ public:
     }
 
     template<typename U>
-    ALWAYS_INLINE RefPtr& operator=(RefPtr<U> const& other)
     requires(IsConvertible<U*, T*>)
+    ALWAYS_INLINE RefPtr& operator=(RefPtr<U> const& other)
     {
         RefPtr tmp { other };
         swap(tmp);
@@ -261,8 +261,8 @@ public:
     bool operator==(NonnullRefPtr<U> const& other) const { return as_ptr() == other.m_ptr; }
 
     template<typename RawPtr>
-    bool operator==(RawPtr other) const
     requires(IsPointer<RawPtr>)
+    bool operator==(RawPtr other) const
     {
         return as_ptr() == other;
     }
@@ -313,8 +313,8 @@ inline RefPtr<T> static_ptr_cast(RefPtr<U> const& ptr)
 }
 
 template<typename T, typename U>
-inline void swap(RefPtr<T>& a, RefPtr<U>& b)
 requires(IsConvertible<U*, T*>)
+inline void swap(RefPtr<T>& a, RefPtr<U>& b)
 {
     a.swap(b);
 }