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

Dmitrii Makarenko via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 5 05:58:14 PST 2026


https://github.com/Devjiu updated https://github.com/llvm/llvm-project/pull/183806

>From 860a7eaeaf400be2439eca6616bd720289b39d89 Mon Sep 17 00:00:00 2001
From: Dmitrii Makarenko <dmitrii.makarenko at intel.com>
Date: Fri, 27 Feb 2026 18:30:14 +0000
Subject: [PATCH] [ADT] Refine MutableArrayRef forwarding constructor
 constraints

Keep MutableArrayRef on a single C&& constructor. This keeps const std::span<int> supported and
rejects const vector/smallvector sources for MutableArrayRef<int>.
---
 llvm/include/llvm/ADT/ArrayRef.h    |  6 +++---
 llvm/unittests/ADT/ArrayRefTest.cpp | 14 ++++++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)

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