[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