[llvm] c88ba88 - [ADT] Refine MutableArrayRef forwarding constructor constraints (#183806)

via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 5 07:09:08 PST 2026


Author: Dmitrii Makarenko
Date: 2026-03-05T10:09:03-05:00
New Revision: c88ba88da52b963692ab30e75821b69dad2c1bbd

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

LOG: [ADT] Refine MutableArrayRef forwarding constructor constraints (#183806)

Keep MutableArrayRef on a single C&& constructor, with SFINAE on direct
check on `C::data()`. This keeps const std::span<int> supported and
rejects const vector/smallvector sources for MutableArrayRef<int>.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/ArrayRef.h
    llvm/unittests/ADT/ArrayRefTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h
index 00b5534469d65..eafc4330a1b1b 100644
--- a/llvm/include/llvm/ADT/ArrayRef.h
+++ b/llvm/include/llvm/ADT/ArrayRef.h
@@ -322,8 +322,8 @@ namespace llvm {
     /// Construct a MutableArrayRef from a range.
     MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
 
-    /// Construct a MutableArrayRef from a type that has a data() method that
-    /// returns a pointer convertible to T *.
+    /// Construct a MutableArrayRef from a type that has data() and size(),
+    /// where data() returns a pointer convertible to T *const *.
     template <typename C,
               typename = std::enable_if_t<
                   std::conjunction_v<
@@ -331,7 +331,7 @@ namespace llvm {
                           decltype(std::declval<C &>().data()) *, T *const *>,
                       std::is_integral<decltype(std::declval<C &>().size())>>,
                   void>>
-    /*implicit*/ constexpr MutableArrayRef(const C &V) : ArrayRef<T>(V) {}
+    /*implicit*/ constexpr MutableArrayRef(C &&V) : ArrayRef<T>(V) {}
 
     /// Construct a MutableArrayRef from a C array.
     template <size_t N>

diff  --git a/llvm/unittests/ADT/ArrayRefTest.cpp b/llvm/unittests/ADT/ArrayRefTest.cpp
index 4c0e31df7adc3..622616f8144f1 100644
--- a/llvm/unittests/ADT/ArrayRefTest.cpp
+++ b/llvm/unittests/ADT/ArrayRefTest.cpp
@@ -340,6 +340,12 @@ static_assert(
 static_assert(!std::is_constructible_v<ArrayRef<TestBase *>,
                                        iterator_range<TestDerived **>>,
               "cannot construct ArrayRef pointer of base type");
+static_assert(!std::is_constructible_v<MutableArrayRef<TestBase>,
+                                       iterator_range<TestDerived *>>,
+              "cannot construct MutableArrayRef base type");
+static_assert(!std::is_constructible_v<MutableArrayRef<TestBase *>,
+                                       iterator_range<TestDerived **>>,
+              "cannot construct MutableArrayRef pointer of base type");
 
 static_assert(
     !std::is_constructible_v<ArrayRef<int>, iterator_range<const int *>>,
@@ -468,6 +474,10 @@ TEST(ArrayRefTest, MutableArrayRefDeductionGuides) {
   }
 }
 
+static_assert(
+    !std::is_constructible_v<MutableArrayRef<int>, const SmallVector<int>>,
+    "cannot construct MutableArrayRef from const std::SmallVector<int>");
+
 #ifdef __cpp_lib_span
 static_assert(std::is_constructible_v<ArrayRef<int>, std::span<const int>>,
               "should be able to construct ArrayRef from const std::span");
@@ -491,6 +501,10 @@ static_assert(
     std::is_constructible_v<MutableArrayRef<int>, const std::span<int>>,
     "should be able to construct MutableArrayRef from const std::span with "
     "mutable elements");
+static_assert(
+    !std::is_constructible_v<MutableArrayRef<TestBase>, std::span<TestDerived>>,
+    "cannot construct MutableArrayRef base type from std::span with derived "
+    "elements");
 #endif
 
 } // end anonymous namespace


        


More information about the llvm-commits mailing list