[libcxx-commits] [libcxx] [libc++]: P4144R1: Remove `span`'s `initializer_list` constructor for C++26 (PR #191428)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Sun Apr 12 19:04:50 PDT 2026


https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/191428

>From 9f72e6e4b98d14a5bc139e90f04b0560d830f2a1 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Fri, 10 Apr 2026 22:20:21 +0800
Subject: [PATCH 1/2] [libc++]: P4144R1: Remove `span`'s `initializer_list`
 constructor

Reverts P2447R6 (implemented in dbbeee6b8357c5a68543f612f3b2b607f1911b4c
). Some test cases that indicate "old" behavior mentioned in P2447R6 are
kept.
---
 libcxx/docs/FeatureTestMacroTable.rst         |  2 -
 libcxx/docs/ReleaseNotes/23.rst               |  1 +
 libcxx/docs/Status/Cxx2cPapers.csv            |  4 +-
 libcxx/include/span                           | 18 +----
 libcxx/include/version                        |  2 -
 .../views/views.span/span.cons/array.pass.cpp |  6 +-
 .../initializer_list.assert.pass.cpp          | 32 --------
 .../span.cons/initializer_list.pass.cpp       | 78 ++-----------------
 .../span.cons/initializer_list.verify.cpp     | 48 ------------
 .../span.cons/iterator_len.verify.cpp         |  6 --
 .../span.version.compile.pass.cpp             | 27 -------
 .../version.version.compile.pass.cpp          | 27 -------
 .../generate_feature_test_macro_components.py |  5 --
 13 files changed, 10 insertions(+), 246 deletions(-)
 delete mode 100644 libcxx/test/std/containers/views/views.span/span.cons/initializer_list.assert.pass.cpp
 delete mode 100644 libcxx/test/std/containers/views/views.span/span.cons/initializer_list.verify.cpp

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 0f65770a4fa14..f975bdb13423c 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -516,8 +516,6 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_span_at``                                      ``202311L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_span_initializer_list``                        ``202311L``
-    ---------------------------------------------------------- -----------------
     ``__cpp_lib_sstream_from_string_view``                     ``202306L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_string_subview``                               ``202506L``
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index aeabfeedfbc5e..b3116bd7e6e9b 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -39,6 +39,7 @@ Implemented Papers
 ------------------
 
 - P2440R1: ``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right`` (`Github <https://llvm.org/PR105184>`__)
+- P4144R1: Remove ``span``'s ``initializer_list`` constructor for C++26 (`Github <https://llvm.org/PR189612>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 6eda9128fda48..d5c5086f57239 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -34,7 +34,7 @@
 "`P2918R2 <https://wg21.link/P2918R2>`__","Runtime format strings II","2023-11 (Kona)","|Complete|","18","`#105394 <https://github.com/llvm/llvm-project/issues/105394>`__",""
 "`P2909R4 <https://wg21.link/P2909R4>`__","Fix formatting of code units as integers (Dude, where’s my ``char``?)","2023-11 (Kona)","|Complete|","18","`#105395 <https://github.com/llvm/llvm-project/issues/105395>`__",""
 "`P0952R2 <https://wg21.link/P0952R2>`__","A new specification for ``std::generate_canonical``","2023-11 (Kona)","","","`#105396 <https://github.com/llvm/llvm-project/issues/105396>`__",""
-"`P2447R6 <https://wg21.link/P2447R6>`__","``std::span`` over an initializer list","2023-11 (Kona)","|Complete|","18","`#105397 <https://github.com/llvm/llvm-project/issues/105397>`__",""
+"`P2447R6 <https://wg21.link/P2447R6>`__","``std::span`` over an initializer list","2023-11 (Kona)","|Complete|","18","`#105397 <https://github.com/llvm/llvm-project/issues/105397>`__","Reverted by `P4144R1 <https://wg21.link/P4144R1>`__."
 "`P2821R5 <https://wg21.link/P2821R5>`__","``span.at()``","2023-11 (Kona)","|Complete|","18","`#105399 <https://github.com/llvm/llvm-project/issues/105399>`__",""
 "`P2868R3 <https://wg21.link/P2868R3>`__","Remove Deprecated ``std::allocator`` Typedef From C++26","2023-11 (Kona)","|Complete|","18","`#105400 <https://github.com/llvm/llvm-project/issues/105400>`__",""
 "`P2870R3 <https://wg21.link/P2870R3>`__","Remove ``basic_string::reserve()`` From C++26","2023-11 (Kona)","|Complete|","18","`#105401 <https://github.com/llvm/llvm-project/issues/105401>`__",""
@@ -200,7 +200,7 @@
 "`P4037R1 <https://wg21.link/P4037R1>`__","Supporting ``signed char`` and ``unsigned char`` in random number generation","2026-03 (Croydon)","","","`#189609 <https://github.com/llvm/llvm-project/issues/189609>`__",""
 "`P3450R1 <https://wg21.link/P3450R1>`__","Extend ``std::is_within_lifetime``","2026-03 (Croydon)","","","`#189610 <https://github.com/llvm/llvm-project/issues/189610>`__",""
 "`P3982R2 <https://wg21.link/P3982R2>`__","Split ``strided_slice`` into ``extent_slice`` and ``range_slice`` for C++26","2026-03 (Croydon)","","","`#189611 <https://github.com/llvm/llvm-project/issues/189611>`__",""
-"`P4144R1 <https://wg21.link/P4144R1>`__","Remove ``span``'s ``initializer_list`` constructor for C++26","2026-03 (Croydon)","","","`#189612 <https://github.com/llvm/llvm-project/issues/189612>`__",""
+"`P4144R1 <https://wg21.link/P4144R1>`__","Remove ``span``'s ``initializer_list`` constructor for C++26","2026-03 (Croydon)","|Complete|","23","`#189612 <https://github.com/llvm/llvm-project/issues/189612>`__",""
 "`P3804R2 <https://wg21.link/P3804R2>`__","Iterating on ``parallel_scheduler``","2026-03 (Croydon)","","","`#189616 <https://github.com/llvm/llvm-project/issues/189616>`__",""
 "`P3787R2 <https://wg21.link/P3787R2>`__","Adjoints to ""Enabling list-initialization for algorithms"": ``uninitialized_fill``","2026-03 (Croydon)","","","`#189618 <https://github.com/llvm/llvm-project/issues/189618>`__",""
 "`P3842R2 <https://wg21.link/P3842R2>`__","A conservative fix for constexpr uncaught_exceptions() and current_exception()","2026-03 (Croydon)","","","`#189619 <https://github.com/llvm/llvm-project/issues/189619>`__",""
diff --git a/libcxx/include/span b/libcxx/include/span
index 1911badd88cb1..f7d77a7de4b9a 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -82,7 +82,6 @@ public:
         constexpr span(const array<value_type, N>& arr) noexcept;
     template<class R>
       constexpr explicit(Extent != dynamic_extent) span(R&& r);
-    constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26
     constexpr span(const span& other) noexcept = default;
     template <class OtherElementType, size_t OtherExtent>
         constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;
@@ -153,6 +152,7 @@ template<class R>
 #  include <__config>
 #  include <__cstddef/byte.h>
 #  include <__cstddef/ptrdiff_t.h>
+#  include <__cstddef/size_t.h>
 #  include <__fwd/array.h>
 #  include <__fwd/span.h>
 #  include <__iterator/bounded_iter.h>
@@ -178,7 +178,6 @@ template<class R>
 #  include <__type_traits/remove_reference.h>
 #  include <__type_traits/type_identity.h>
 #  include <__utility/forward.h>
-#  include <initializer_list>
 #  include <stdexcept>
 #  include <version>
 
@@ -254,15 +253,6 @@ public:
     requires(_Sz == 0)
   _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {}
 
-#    if _LIBCPP_STD_VER >= 26
-  _LIBCPP_HIDE_FROM_ABI constexpr explicit span(std::initializer_list<value_type> __il)
-    requires is_const_v<element_type>
-      : __data_{__il.begin()} {
-    _LIBCPP_ASSERT_VALID_INPUT_RANGE(
-        _Extent == __il.size(), "Size mismatch in span's constructor _Extent != __il.size().");
-  }
-#    endif
-
   constexpr span(const span&) noexcept            = default;
   constexpr span& operator=(const span&) noexcept = default;
 
@@ -443,12 +433,6 @@ public:
   // [span.cons], span constructors, copy, assignment, and destructor
   _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {}
 
-#    if _LIBCPP_STD_VER >= 26
-  _LIBCPP_HIDE_FROM_ABI constexpr span(std::initializer_list<value_type> __il)
-    requires is_const_v<element_type>
-      : __data_{__il.begin()}, __size_{__il.size()} {}
-#    endif
-
   constexpr span(const span&) noexcept            = default;
   constexpr span& operator=(const span&) noexcept = default;
 
diff --git a/libcxx/include/version b/libcxx/include/version
index c43d36e569efb..114b0d5a01300 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -243,7 +243,6 @@ __cpp_lib_smart_ptr_owner_equality                      202306L <memory>
 __cpp_lib_source_location                               201907L <source_location>
 __cpp_lib_span                                          202002L <span>
 __cpp_lib_span_at                                       202311L <span>
-__cpp_lib_span_initializer_list                         202311L <span>
 __cpp_lib_spanstream                                    202106L <spanstream>
 __cpp_lib_ssize                                         201902L <iterator>
 __cpp_lib_sstream_from_string_view                      202306L <sstream>
@@ -616,7 +615,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_senders                              202406L
 // # define __cpp_lib_smart_ptr_owner_equality             202306L
 # define __cpp_lib_span_at                              202311L
-# define __cpp_lib_span_initializer_list                202311L
 # define __cpp_lib_sstream_from_string_view             202306L
 # define __cpp_lib_string_subview                       202506L
 # undef  __cpp_lib_string_view
diff --git a/libcxx/test/std/containers/views/views.span/span.cons/array.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/array.pass.cpp
index ad9f44aa474c6..6e40aef8521ea 100644
--- a/libcxx/test/std/containers/views/views.span/span.cons/array.pass.cpp
+++ b/libcxx/test/std/containers/views/views.span/span.cons/array.pass.cpp
@@ -91,12 +91,8 @@ constexpr bool testSpan() {
 
   TEST_DIAGNOSTIC_PUSH
   TEST_CLANG_DIAGNOSTIC_IGNORED("-Wdangling")
-  std::span<const int> s5 = {{1, 2}};
-#if TEST_STD_VER >= 26
-  std::span<const int, 2> s6({1, 2});
-#else
+  std::span<const int> s5    = {{1, 2}};
   std::span<const int, 2> s6 = {{1, 2}};
-#endif
   assert(s5.size() == 2); // and it dangles
   assert(s6.size() == 2); // and it dangles
   TEST_DIAGNOSTIC_POP
diff --git a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.assert.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.assert.pass.cpp
deleted file mode 100644
index 262e56c74287d..0000000000000
--- a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.assert.pass.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: availability-verbose_abort-missing
-
-// <span>
-
-// constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26
-
-#include <cassert>
-#include <initializer_list>
-#include <span>
-
-#include "check_assertion.h"
-
-int main(int, char**) {
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::span<const int, 4>({1, 2, 3, 9084, 5})), "Size mismatch in span's constructor _Extent != __il.size().");
-  TEST_LIBCPP_ASSERT_FAILURE((std::span<const int, 4>(std::initializer_list<int>{1, 2, 3, 9084, 5})),
-                             "Size mismatch in span's constructor _Extent != __il.size().");
-
-  return 0;
-}
diff --git a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp
index b413b71ec9458..4cfe7c2a36fd5 100644
--- a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp
@@ -10,51 +10,14 @@
 
 // <span>
 
-// constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26
-
 #include <any>
 #include <cassert>
 #include <cstddef>
-#include <initializer_list>
 #include <span>
-#include <type_traits>
 
 #include "test_convertible.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// SFINAE
-
-template <typename T>
-concept ConstElementType = std::is_const_v<typename T::element_type>;
-
-static_assert(ConstElementType<std::span<const int>>);
-static_assert(!ConstElementType<std::span<int>>);
-static_assert(ConstElementType<std::span<const int, 94>>);
-static_assert(!ConstElementType<std::span<int, 94>>);
-
-// Constructor constraints
-
-template <typename I, typename T, std::size_t... N>
-concept HasInitializerListCtr = requires(I il) { std::span<T, N...>{il}; };
-
-static_assert(HasInitializerListCtr<std::initializer_list<const int>, const int>);
-static_assert(!HasInitializerListCtr<std::initializer_list<int>, int>);
-static_assert(HasInitializerListCtr<std::initializer_list<const int>, const int, 94>);
-static_assert(!HasInitializerListCtr<std::initializer_list<int>, int, 94>);
-
-// Constructor conditionally explicit
-
-static_assert(!test_convertible<std::span<const int, 28>, std::initializer_list<int>>(),
-              "This constructor must be explicit");
-static_assert(std::is_constructible_v<std::span<const int, 28>, std::initializer_list<int>>);
-static_assert(test_convertible<std::span<const int>, std::initializer_list<int>>(),
-              "This constructor must not be explicit");
-static_assert(std::is_constructible_v<std::span<const int>, std::initializer_list<int>>);
-
-#endif
-
 struct Sink {
   constexpr Sink() = default;
   constexpr Sink(Sink*) {}
@@ -68,53 +31,23 @@ constexpr std::size_t count_n(std::span<const Sink, N> sp) {
 }
 
 constexpr bool test() {
-#if TEST_STD_VER >= 26
-  // Dynamic extent
-  {
-    Sink a[10];
+  Sink a[10];
 
-    assert(count({a}) == 1);
-    assert(count({a, a + 10}) == 2);
-    assert(count({a, a + 1, a + 2}) == 3);
-    assert(count(std::initializer_list<Sink>{a[0], a[1], a[2], a[3]}) == 4);
-  }
-#else
-  {
-    Sink a[10];
-
-    assert(count({a}) == 10);
-    assert(count({a, a + 10}) == 10);
-    assert(count_n<10>({a}) == 10);
-  }
-#endif
+  assert(count({a}) == 10);
+  assert(count({a, a + 10}) == 10);
+  assert(count_n<10>({a}) == 10);
 
   return true;
 }
 
 // Test P2447R4 "Annex C examples"
+// P2447R4 was revert by P4144R1, so we only test the "old" behavior
 
 constexpr int three(std::span<void* const> sp) { return static_cast<int>(sp.size()); }
 
 constexpr int four(std::span<const std::any> sp) { return static_cast<int>(sp.size()); }
 
 bool test_P2447R4_annex_c_examples() {
-  // 1. Overload resolution is affected
-  // --> tested in "initializer_list.verify.cpp"
-
-  // 2. The `initializer_list` ctor has high precedence
-  // --> tested in "initializer_list.verify.cpp"
-
-  // 3. Implicit two-argument construction with a highly convertible value_type
-#if TEST_STD_VER >= 26
-  {
-    void* a[10];
-    assert(three({a, 0}) == 2);
-  }
-  {
-    std::any a[10];
-    assert(four({a, a + 10}) == 2);
-  }
-#else
   {
     void* a[10];
     assert(three({a, 0}) == 0);
@@ -123,7 +56,6 @@ bool test_P2447R4_annex_c_examples() {
     std::any a[10];
     assert(four({a, a + 10}) == 10);
   }
-#endif
 
   return true;
 }
diff --git a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.verify.cpp b/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.verify.cpp
deleted file mode 100644
index 93bcd0551cdb0..0000000000000
--- a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.verify.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// <span>
-
-// constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26
-
-#include <span>
-#include <utility>
-
-#include "test_macros.h"
-
-// Test P2447R4 "Annex C examples"
-
-void one(std::pair<int, int>);
-void one(std::span<const int>);
-
-void two(std::span<const int, 2>);
-
-void test_P2447R4_annex_c_examples() {
-  // 1. Overload resolution is affected
-#if TEST_STD_VER >= 26
-  // expected-error at +1 {{call to 'one' is ambiguous}}
-  one({1, 2});
-#else
-  // expected-no-diagnostics
-  one({1, 2});
-#endif
-
-// 2. The `initializer_list` ctor has high precedence
-#if TEST_STD_VER >= 26
-  // expected-error at +1 {{chosen constructor is explicit in copy-initialization}}
-  two({{1, 2}});
-#else
-  // expected-no-diagnostics
-  two({{1, 2}});
-#endif
-
-  // 3. Implicit two-argument construction with a highly convertible value_type
-  // --> tested in "initializer_list.pass.cpp"
-}
diff --git a/libcxx/test/std/containers/views/views.span/span.cons/iterator_len.verify.cpp b/libcxx/test/std/containers/views/views.span/span.cons/iterator_len.verify.cpp
index 176ca20079269..0122d65e46612 100644
--- a/libcxx/test/std/containers/views/views.span/span.cons/iterator_len.verify.cpp
+++ b/libcxx/test/std/containers/views/views.span/span.cons/iterator_len.verify.cpp
@@ -12,14 +12,10 @@
 // template <class It>
 // constexpr explicit(Extent != dynamic_extent) span(It first, size_type count);
 //  If Extent is not equal to dynamic_extent, then count shall be equal to Extent.
-//
-// constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26
 
 #include <span>
 #include <cstddef>
 
-#include "test_macros.h"
-
 template <class T, std::size_t extent>
 std::span<T, extent> createImplicitSpan(T* ptr, std::size_t len) {
   return {ptr, len}; // expected-error {{chosen constructor is explicit in copy-initialization}}
@@ -34,10 +30,8 @@ void test() {
   std::span<int> sp = {0, 0};
   // expected-error at +1 {{no matching constructor for initialization of 'std::span<int, 2>'}}
   std::span<int, 2> sp2 = {0, 0};
-#if TEST_STD_VER < 26
   // expected-error at +1 {{no matching constructor for initialization of 'std::span<const int>'}}
   std::span<const int> csp = {0, 0};
   // expected-error at +1 {{no matching constructor for initialization of 'std::span<const int, 2>'}}
   std::span<const int, 2> csp2 = {0, 0};
-#endif
 }
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
index 826471a65f691..28c54acd0fda2 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
@@ -28,10 +28,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #elif TEST_STD_VER == 14
 
 #  ifdef __cpp_lib_span
@@ -42,10 +38,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #elif TEST_STD_VER == 17
 
 #  ifdef __cpp_lib_span
@@ -56,10 +48,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #elif TEST_STD_VER == 20
 
 #  ifndef __cpp_lib_span
@@ -73,10 +61,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #elif TEST_STD_VER == 23
 
 #  ifndef __cpp_lib_span
@@ -90,10 +74,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #elif TEST_STD_VER > 23
 
 #  ifndef __cpp_lib_span
@@ -110,13 +90,6 @@
 #    error "__cpp_lib_span_at should have the value 202311L in c++26"
 #  endif
 
-#  ifndef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should be defined in c++26"
-#  endif
-#  if __cpp_lib_span_initializer_list != 202311L
-#    error "__cpp_lib_span_initializer_list should have the value 202311L in c++26"
-#  endif
-
 #endif // TEST_STD_VER > 23
 
 // clang-format on
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index a1c8755af4ad9..6d49f29b59065 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -796,10 +796,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #  ifdef __cpp_lib_spanstream
 #    error "__cpp_lib_spanstream should not be defined before c++23"
 #  endif
@@ -1767,10 +1763,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #  ifdef __cpp_lib_spanstream
 #    error "__cpp_lib_spanstream should not be defined before c++23"
 #  endif
@@ -2918,10 +2910,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #  ifdef __cpp_lib_spanstream
 #    error "__cpp_lib_spanstream should not be defined before c++23"
 #  endif
@@ -4330,10 +4318,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #  ifdef __cpp_lib_spanstream
 #    error "__cpp_lib_spanstream should not be defined before c++23"
 #  endif
@@ -5949,10 +5933,6 @@
 #    error "__cpp_lib_span_at should not be defined before c++26"
 #  endif
 
-#  ifdef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should not be defined before c++26"
-#  endif
-
 #  if !defined(_LIBCPP_VERSION)
 #    ifndef __cpp_lib_spanstream
 #      error "__cpp_lib_spanstream should be defined in c++23"
@@ -7913,13 +7893,6 @@
 #    error "__cpp_lib_span_at should have the value 202311L in c++26"
 #  endif
 
-#  ifndef __cpp_lib_span_initializer_list
-#    error "__cpp_lib_span_initializer_list should be defined in c++26"
-#  endif
-#  if __cpp_lib_span_initializer_list != 202311L
-#    error "__cpp_lib_span_initializer_list should have the value 202311L in c++26"
-#  endif
-
 #  if !defined(_LIBCPP_VERSION)
 #    ifndef __cpp_lib_spanstream
 #      error "__cpp_lib_spanstream should be defined in c++26"
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index c5f81ca172f5a..d056eb206444c 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1305,11 +1305,6 @@ def add_version_header(tc):
             "values": {"c++26": 202311},  # P2821R3 span.at()
             "headers": ["span"],
         },
-        {
-            "name": "__cpp_lib_span_initializer_list",
-            "values": {"c++26": 202311},  # P2447R6 std::span over an initializer list
-            "headers": ["span"],
-        },
         {
             "name": "__cpp_lib_spanstream",
             "values": {"c++23": 202106},

>From 3f92c0edf0aed3ff70cbf2d500063fda84131daa Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 13 Apr 2026 10:04:40 +0800
Subject: [PATCH 2/2] Fix typo

---
 .../views/views.span/span.cons/initializer_list.pass.cpp        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp
index 4cfe7c2a36fd5..a19d33f0816ba 100644
--- a/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/views/views.span/span.cons/initializer_list.pass.cpp
@@ -41,7 +41,7 @@ constexpr bool test() {
 }
 
 // Test P2447R4 "Annex C examples"
-// P2447R4 was revert by P4144R1, so we only test the "old" behavior
+// P2447R4 was reverted by P4144R1, so we only test the "old" behavior.
 
 constexpr int three(std::span<void* const> sp) { return static_cast<int>(sp.size()); }
 



More information about the libcxx-commits mailing list