[libcxx-commits] [libcxx] [libc++][format] P3953R3: Rename `std::runtime_format` (PR #189657)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 31 12:51:06 PDT 2026


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/189657

>From 36a224963955ef0d5fdc99590a35521ada6ac860 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 31 Mar 2026 16:16:15 +0300
Subject: [PATCH 1/3] [libc++][format] P3953R3: Rename std::runtime_format

Implements P3953R3

-  https://github.com/cplusplus/draft/pull/8879
- https://isocpp.org/files/papers/P3953R3.html
---
 libcxx/docs/ReleaseNotes/23.rst               |  1 +
 libcxx/include/__format/format_functions.h    | 14 ++++++-------
 libcxx/include/format                         |  4 ++--
 libcxx/modules/std/format.inc                 |  2 +-
 .../ctor.runtime-format-string.pass.cpp       | 12 +++++------
 .../format.locale.runtime_format.pass.cpp     | 12 +++++------
 .../format.runtime_format.pass.cpp            | 12 +++++------
 .../format.syn/runtime_format_string.pass.cpp | 20 +++++++++----------
 .../generate_feature_test_macro_components.py |  1 +
 9 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index aeabfeedfbc5e..00e25dc67fa31 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>`__)
+- P3953R3: Rename ``std::runtime_format``
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 7b0fcc0ea585a..7cf259d0e1db7 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -342,7 +342,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator __vformat_to(_ParseCtx&&
 
 #  if _LIBCPP_STD_VER >= 26
 template <class _CharT>
-struct __runtime_format_string {
+struct __dynamic_format_string {
 private:
   basic_string_view<_CharT> __str_;
 
@@ -350,15 +350,15 @@ struct __runtime_format_string {
   friend struct basic_format_string;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __runtime_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
+  _LIBCPP_HIDE_FROM_ABI __dynamic_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
 
-  __runtime_format_string(const __runtime_format_string&)            = delete;
-  __runtime_format_string& operator=(const __runtime_format_string&) = delete;
+  __dynamic_format_string(const __dynamic_format_string&)            = delete;
+  __dynamic_format_string& operator=(const __dynamic_format_string&) = delete;
 };
 
-_LIBCPP_HIDE_FROM_ABI inline __runtime_format_string<char> runtime_format(string_view __fmt) noexcept { return __fmt; }
+_LIBCPP_HIDE_FROM_ABI inline __dynamic_format_string<char> dynamic_format(string_view __fmt) noexcept { return __fmt; }
 #    if _LIBCPP_HAS_WIDE_CHARACTERS
-_LIBCPP_HIDE_FROM_ABI inline __runtime_format_string<wchar_t> runtime_format(wstring_view __fmt) noexcept {
+_LIBCPP_HIDE_FROM_ABI inline __dynamic_format_string<wchar_t> dynamic_format(wstring_view __fmt) noexcept {
   return __fmt;
 }
 #    endif
@@ -375,7 +375,7 @@ struct basic_format_string {
 
   _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { return __str_; }
 #  if _LIBCPP_STD_VER >= 26
-  _LIBCPP_HIDE_FROM_ABI basic_format_string(__runtime_format_string<_CharT> __s) noexcept : __str_(__s.__str_) {}
+  _LIBCPP_HIDE_FROM_ABI basic_format_string(__dynamic_format_string<_CharT> __s) noexcept : __str_(__s.__str_) {}
 #  endif
 
 private:
diff --git a/libcxx/include/format b/libcxx/include/format
index 2246f062040ae..45dbae436dc3c 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -53,10 +53,10 @@ namespace std {
     runtime-format-string& operator=(const runtime-format-string&) = delete;
   };
 
-  runtime-format-string<char> runtime_format(string_view fmt) noexcept {
+  runtime-format-string<char> dynamic_format(string_view fmt) noexcept {
     return fmt;
   }
-  runtime-format-string<wchar_t> runtime_format(wstring_view fmt) noexcept {
+  runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept {
     return fmt;
   }
 
diff --git a/libcxx/modules/std/format.inc b/libcxx/modules/std/format.inc
index fb0f971aeb0e9..baa43bc8304dc 100644
--- a/libcxx/modules/std/format.inc
+++ b/libcxx/modules/std/format.inc
@@ -29,7 +29,7 @@ export namespace std {
   using std::wformat_string;
 #endif
 #if _LIBCPP_STD_VER >= 26
-  using std::runtime_format;
+  using std::dynamic_format;
 #endif // _LIBCPP_STD_VER >= 26
 
   // [format.functions], formatting functions
diff --git a/libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp b/libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
index fff15a1da4017..d5bebadf6596a 100644
--- a/libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
@@ -16,8 +16,8 @@
 // basic_format_string(runtime-format-string<charT> s) noexcept : str(s.str) {}
 //
 // Additional testing is done in
-// - libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
-// - libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
+// - libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp
+// - libcxx/test/std/utilities/format/format.functions/format.locale.dynamic_format.pass.cpp
 
 #include <format>
 #include <cassert>
@@ -25,16 +25,16 @@
 #include "test_macros.h"
 
 int main(int, char**) {
-  static_assert(noexcept(std::format_string<>{std::runtime_format(std::string_view{})}));
+  static_assert(noexcept(std::format_string<>{std::dynamic_format(std::string_view{})}));
   {
-    std::format_string<> s = std::runtime_format("}{invalid format string}{");
+    std::format_string<> s = std::dynamic_format("}{invalid format string}{");
     assert(s.get() == "}{invalid format string}{");
   }
 
 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-  static_assert(noexcept(std::wformat_string<>{std::runtime_format(std::wstring_view{})}));
+  static_assert(noexcept(std::wformat_string<>{std::dynamic_format(std::wstring_view{})}));
   {
-    std::wformat_string<> s = std::runtime_format(L"}{invalid format string}{");
+    std::wformat_string<> s = std::dynamic_format(L"}{invalid format string}{");
     assert(s.get() == L"}{invalid format string}{");
   }
 #endif // TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp b/libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
index a262d64f4579b..4044ac8dc3b6d 100644
--- a/libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
@@ -16,8 +16,8 @@
 
 // Tests the behavior of
 //
-// runtime-format-string<char> runtime_format(string_view fmt) noexcept;
-// runtime-format-string<wchar_t> runtime_format(wstring_view fmt) noexcept;
+// runtime-format-string<char> dynamic_format(string_view fmt) noexcept;
+// runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
 //
 // and
 //
@@ -35,8 +35,8 @@
 // template<class... Args>
 //   wstring format(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
 //
-// The basics of runtime_format and basic_format_string's constructor are tested in
-// - libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
+// The basics of dynamic_format and basic_format_string's constructor are tested in
+// - libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
 // - libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
 
 #include <format>
@@ -52,7 +52,7 @@
 
 auto test = []<class CharT, class... Args>(
                 std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) constexpr {
-  std::basic_string<CharT> out = std::format(std::locale(), std::runtime_format(fmt), std::forward<Args>(args)...);
+  std::basic_string<CharT> out = std::format(std::locale(), std::dynamic_format(fmt), std::forward<Args>(args)...);
   TEST_REQUIRE(out == expected,
                TEST_WRITE_CONCATENATED(
                    "\nFormat string   ", fmt, "\nExpected output ", expected, "\nActual output   ", out, '\n'));
@@ -71,7 +71,7 @@ auto test_exception =
                 TEST_WRITE_CONCATENATED(
                     "\nFormat string   ", fmt, "\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));
           },
-          TEST_IGNORE_NODISCARD std::format(std::locale(), std::runtime_format(fmt), std::forward<Args>(args)...));
+          TEST_IGNORE_NODISCARD std::format(std::locale(), std::dynamic_format(fmt), std::forward<Args>(args)...));
     };
 
 int main(int, char**) {
diff --git a/libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp b/libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
index 4bec9094382de..e56ccc170acae 100644
--- a/libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
@@ -15,8 +15,8 @@
 
 // Tests the behavior of
 //
-// runtime-format-string<char> runtime_format(string_view fmt) noexcept;
-// runtime-format-string<wchar_t> runtime_format(wstring_view fmt) noexcept;
+// runtime-format-string<char> dynamic_format(string_view fmt) noexcept;
+// runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
 //
 // and
 //
@@ -34,8 +34,8 @@
 // template<class... Args>
 //   wstring format(wformat_string<Args...> fmt, Args&&... args);
 //
-// The basics of runtime_format and basic_format_string's constructor are tested in
-// - libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
+// The basics of dynamic_format and basic_format_string's constructor are tested in
+// - libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
 // - libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
 
 #include <format>
@@ -50,7 +50,7 @@
 
 auto test = []<class CharT, class... Args>(
                 std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) constexpr {
-  std::basic_string<CharT> out = std::format(std::runtime_format(fmt), std::forward<Args>(args)...);
+  std::basic_string<CharT> out = std::format(std::dynamic_format(fmt), std::forward<Args>(args)...);
   TEST_REQUIRE(out == expected,
                TEST_WRITE_CONCATENATED(
                    "\nFormat string   ", fmt, "\nExpected output ", expected, "\nActual output   ", out, '\n'));
@@ -69,7 +69,7 @@ auto test_exception =
                 TEST_WRITE_CONCATENATED(
                     "\nFormat string   ", fmt, "\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));
           },
-          TEST_IGNORE_NODISCARD std::format(std::runtime_format(fmt), std::forward<Args>(args)...));
+          TEST_IGNORE_NODISCARD std::format(std::dynamic_format(fmt), std::forward<Args>(args)...));
     };
 
 int main(int, char**) {
diff --git a/libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp b/libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
index c2a221c233ba4..8bf56a975be7f 100644
--- a/libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
@@ -21,12 +21,12 @@
 //   runtime-format-string& operator=(const runtime-format-string&) = delete;
 // };
 //
-// runtime-format-string<char> runtime_format(string_view fmt) noexcept;
-// runtime-format-string<wchar_t> runtime_format(wstring_view fmt) noexcept;
+// runtime-format-string<char> dynamic_format(string_view fmt) noexcept;
+// runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
 //
 // Additional testing is done in
-// - libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
-// - libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
+// - libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp
+// - libcxx/test/std/utilities/format/format.functions/format.locale.dynamic_format.pass.cpp
 
 #include <format>
 
@@ -50,19 +50,19 @@ static void test_properties() {
 }
 
 int main(int, char**) {
-  static_assert(noexcept(std::runtime_format(std::string_view{})));
-  auto format_string = std::runtime_format(std::string_view{});
+  static_assert(noexcept(std::dynamic_format(std::string_view{})));
+  auto format_string = std::dynamic_format(std::string_view{});
 
   using FormatString = decltype(format_string);
-  LIBCPP_ASSERT((std::same_as<FormatString, std::__runtime_format_string<char>>));
+  LIBCPP_ASSERT((std::same_as<FormatString, std::__dynamic_format_string<char>>));
   test_properties<FormatString, char>();
 
 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-  static_assert(noexcept(std::runtime_format(std::wstring_view{})));
-  auto wformat_string = std::runtime_format(std::wstring_view{});
+  static_assert(noexcept(std::dynamic_format(std::wstring_view{})));
+  auto wformat_string = std::dynamic_format(std::wstring_view{});
 
   using WFormatString = decltype(wformat_string);
-  LIBCPP_ASSERT((std::same_as<WFormatString, std::__runtime_format_string<wchar_t>>));
+  LIBCPP_ASSERT((std::same_as<WFormatString, std::__dynamic_format_string<wchar_t>>));
   test_properties<WFormatString, wchar_t>();
 #endif // TEST_HAS_NO_WIDE_CHARACTERS
 
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index c5f81ca172f5a..a2e43445411da 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -572,6 +572,7 @@ def add_version_header(tc):
                 # "c++23": 202207, Not implemented P2419R2 Clarify handling of encodings in localized formatting of chrono types
                 # "c++26": 202306, P2637R3 Member Visit (implemented)
                 # "c++26": 202311, P2918R2 Runtime format strings II (implemented)
+                # "c++26": 202603, P3953R3 Rename std::runtime_format
             },
             # Note these three papers are adopted at the June 2023 meeting and have sequential numbering
             # 202304 P2510R3 Formatting pointers (Implemented)

>From f9e3c6d17d1ba7022de2c92669246a3c2a756ccd Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 31 Mar 2026 16:49:01 +0300
Subject: [PATCH 2/3] Renamed test files

---
 libcxx/include/format                              | 14 +++++++-------
 ...ass.cpp => ctor.dynamic-format-string.pass.cpp} |  2 +-
 ...mat.pass.cpp => format.dynamic_format.pass.cpp} |  8 ++++----
 ...s.cpp => format.locale.dynamic_format.pass.cpp} |  8 ++++----
 ...ing.pass.cpp => dynamic_format_string.pass.cpp} | 12 ++++++------
 5 files changed, 22 insertions(+), 22 deletions(-)
 rename libcxx/test/std/utilities/format/format.fmt.string/{ctor.runtime-format-string.pass.cpp => ctor.dynamic-format-string.pass.cpp} (95%)
 rename libcxx/test/std/utilities/format/format.functions/{format.runtime_format.pass.cpp => format.dynamic_format.pass.cpp} (90%)
 rename libcxx/test/std/utilities/format/format.functions/{format.locale.runtime_format.pass.cpp => format.locale.dynamic_format.pass.cpp} (90%)
 rename libcxx/test/std/utilities/format/format.syn/{runtime_format_string.pass.cpp => dynamic_format_string.pass.cpp} (84%)

diff --git a/libcxx/include/format b/libcxx/include/format
index 45dbae436dc3c..7ff619fa84208 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -31,7 +31,7 @@ namespace std {
 
     public:
       template<class T> consteval basic_format_string(const T& s);
-      basic_format_string(runtime-format-string<charT> s) noexcept : str(s.str) {}   // since C++26
+      basic_format_string(dynamic-format-string<charT> s) noexcept : str(s.str) {}   // since C++26
 
       constexpr basic_string_view<charT> get() const noexcept { return str; }
     };
@@ -42,21 +42,21 @@ namespace std {
     using wformat_string =                                      // since C++23, exposition only before C++23
       basic_format_string<wchar_t, type_identity_t<Args>...>;
 
-  template<class charT> struct runtime-format-string {          // since C++26, exposition-only
+  template<class charT> struct dynamic-format-string {          // since C++26, exposition-only
   private:
     basic_string_view<charT> str;                               // exposition-only
 
   public:
-    runtime-format-string(basic_string_view<charT> s) noexcept : str(s) {}
+    dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {}
 
-    runtime-format-string(const runtime-format-string&) = delete;
-    runtime-format-string& operator=(const runtime-format-string&) = delete;
+    dynamic-format-string(const dynamic-format-string&) = delete;
+    dynamic-format-string& operator=(const dynamic-format-string&) = delete;
   };
 
-  runtime-format-string<char> dynamic_format(string_view fmt) noexcept {
+  dynamic-format-string<char> dynamic_format(string_view fmt) noexcept {
     return fmt;
   }
-  runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept {
+  dynamic-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept {
     return fmt;
   }
 
diff --git a/libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp b/libcxx/test/std/utilities/format/format.fmt.string/ctor.dynamic-format-string.pass.cpp
similarity index 95%
rename from libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
rename to libcxx/test/std/utilities/format/format.fmt.string/ctor.dynamic-format-string.pass.cpp
index d5bebadf6596a..f839e8fb5d946 100644
--- a/libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.fmt.string/ctor.dynamic-format-string.pass.cpp
@@ -13,7 +13,7 @@
 // template<class charT, class... Args>
 // class basic_format_string<charT, type_identity_t<Args>...>
 //
-// basic_format_string(runtime-format-string<charT> s) noexcept : str(s.str) {}
+// basic_format_string(dynamic-format-string<charT> s) noexcept : str(s.str) {}
 //
 // Additional testing is done in
 // - libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp
diff --git a/libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp b/libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp
similarity index 90%
rename from libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
rename to libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp
index e56ccc170acae..8193eb2a71750 100644
--- a/libcxx/test/std/utilities/format/format.functions/format.runtime_format.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp
@@ -15,15 +15,15 @@
 
 // Tests the behavior of
 //
-// runtime-format-string<char> dynamic_format(string_view fmt) noexcept;
-// runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
+// dynamic-format-string<char> dynamic_format(string_view fmt) noexcept;
+// dynamic-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
 //
 // and
 //
 // template<class charT, class... Args>
 //   struct basic_format_string {
 //   ...
-//   basic_format_string(runtime-format-string<charT> s) noexcept : str(s.str) {}
+//   basic_format_string(dynamic-format-string<charT> s) noexcept : str(s.str) {}
 //   ...
 // }
 //
@@ -36,7 +36,7 @@
 //
 // The basics of dynamic_format and basic_format_string's constructor are tested in
 // - libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
-// - libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
+// - libcxx/test/std/utilities/format/format.fmt.string/ctor.dynamic-format-string.pass.cpp
 
 #include <format>
 #include <cassert>
diff --git a/libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp b/libcxx/test/std/utilities/format/format.functions/format.locale.dynamic_format.pass.cpp
similarity index 90%
rename from libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
rename to libcxx/test/std/utilities/format/format.functions/format.locale.dynamic_format.pass.cpp
index 4044ac8dc3b6d..780c9d0f3832b 100644
--- a/libcxx/test/std/utilities/format/format.functions/format.locale.runtime_format.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.functions/format.locale.dynamic_format.pass.cpp
@@ -16,15 +16,15 @@
 
 // Tests the behavior of
 //
-// runtime-format-string<char> dynamic_format(string_view fmt) noexcept;
-// runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
+// dynamic-format-string<char> dynamic_format(string_view fmt) noexcept;
+// dynamic-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
 //
 // and
 //
 // template<class charT, class... Args>
 //   struct basic_format_string {
 //   ...
-//   basic_format_string(runtime-format-string<charT> s) noexcept : str(s.str) {}
+//   basic_format_string(dynamic-format-string<charT> s) noexcept : str(s.str) {}
 //   ...
 // }
 //
@@ -37,7 +37,7 @@
 //
 // The basics of dynamic_format and basic_format_string's constructor are tested in
 // - libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
-// - libcxx/test/std/utilities/format/format.fmt.string/ctor.runtime-format-string.pass.cpp
+// - libcxx/test/std/utilities/format/format.fmt.string/ctor.dynamic-format-string.pass.cpp
 
 #include <format>
 #include <cassert>
diff --git a/libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp b/libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
similarity index 84%
rename from libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
rename to libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
index 8bf56a975be7f..634a28a082581 100644
--- a/libcxx/test/std/utilities/format/format.syn/runtime_format_string.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.syn/dynamic_format_string.pass.cpp
@@ -10,19 +10,19 @@
 
 // <format>
 
-// template<class charT> struct runtime-format-string {  // exposition-only
+// template<class charT> struct dynamic-format-string {  // exposition-only
 // private:
 //   basic_string_view<charT> str;  // exposition-only
 //
 // public:
-//   runtime-format-string(basic_string_view<charT> s) noexcept : str(s) {}
+//   dynamic-format-string(basic_string_view<charT> s) noexcept : str(s) {}
 //
-//   runtime-format-string(const runtime-format-string&) = delete;
-//   runtime-format-string& operator=(const runtime-format-string&) = delete;
+//   dynamic-format-string(const dynamic-format-string&) = delete;
+//   dynamic-format-string& operator=(const dynamic-format-string&) = delete;
 // };
 //
-// runtime-format-string<char> dynamic_format(string_view fmt) noexcept;
-// runtime-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
+// dynamic-format-string<char> dynamic_format(string_view fmt) noexcept;
+// dynamic-format-string<wchar_t> dynamic_format(wstring_view fmt) noexcept;
 //
 // Additional testing is done in
 // - libcxx/test/std/utilities/format/format.functions/format.dynamic_format.pass.cpp

>From a857734f02cf83c7d14fa57520577a26131d80ee Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hristo.goshev.hristov at gmail.com>
Date: Tue, 31 Mar 2026 22:50:54 +0300
Subject: [PATCH 3/3] Apply suggestions from code review

Thanks!

Co-authored-by: A. Jiang <de34 at live.cn>
---
 libcxx/docs/ReleaseNotes/23.rst                        | 2 +-
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index 00e25dc67fa31..fe80e4cd6f3fb 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -39,7 +39,7 @@ Implemented Papers
 ------------------
 
 - P2440R1: ``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right`` (`Github <https://llvm.org/PR105184>`__)
-- P3953R3: Rename ``std::runtime_format``
+- P3953R3: Rename ``std::runtime_format`` (`Github <https://llvm.org/PR189624>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index a2e43445411da..6bfaf4af41c2e 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -572,7 +572,7 @@ def add_version_header(tc):
                 # "c++23": 202207, Not implemented P2419R2 Clarify handling of encodings in localized formatting of chrono types
                 # "c++26": 202306, P2637R3 Member Visit (implemented)
                 # "c++26": 202311, P2918R2 Runtime format strings II (implemented)
-                # "c++26": 202603, P3953R3 Rename std::runtime_format
+                # "c++26": 202603, P3953R3 Rename std::runtime_format (implemented)
             },
             # Note these three papers are adopted at the June 2023 meeting and have sequential numbering
             # 202304 P2510R3 Formatting pointers (Implemented)



More information about the libcxx-commits mailing list