diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index 6371298..66a1747 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -20,7 +20,6 @@
   "base/internal/dynamic_annotations.h"
   "base/internal/endian.h"
   "base/internal/errno_saver.h"
-  "base/internal/hardening.cc"
   "base/internal/hardening.h"
   "base/internal/hide_ptr.h"
   "base/internal/iterator_traits.h"
@@ -287,6 +286,9 @@
   "status/internal/statusor_internal.h"
   "status/status.cc"
   "status/status.h"
+  "status/status_builder.cc"
+  "status/status_builder.h"
+  "status/status_macros.h"
   "status/status_payload_printer.cc"
   "status/status_payload_printer.h"
   "status/statusor.cc"
diff --git a/MODULE.bazel b/MODULE.bazel
index edb49d0..cc60d22 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -17,7 +17,6 @@
 module(
     name = "abseil-cpp",
     version = "head",
-    compatibility_level = 1,
 )
 
 cc_configure = use_extension("@rules_cc//cc:extensions.bzl",
@@ -25,9 +24,9 @@
                              dev_dependency = True)
 use_repo(cc_configure, "local_config_cc")
 
-bazel_dep(name = "rules_cc", version = "0.2.9")
-bazel_dep(name = "bazel_skylib", version = "1.8.1")
-bazel_dep(name = "platforms", version = "1.0.0")
+bazel_dep(name = "rules_cc", version = "0.2.18")
+bazel_dep(name = "bazel_skylib", version = "1.9.0")
+bazel_dep(name = "platforms", version = "1.1.0")
 
 bazel_dep(
     name = "google_benchmark",
diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel
index 7d8350c..cdb0af1 100644
--- a/absl/algorithm/BUILD.bazel
+++ b/absl/algorithm/BUILD.bazel
@@ -41,6 +41,7 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:config",
+        "//absl/base:core_headers",
     ],
 )
 
@@ -69,6 +70,8 @@
         ":algorithm",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:hardening",
+        "//absl/base:iterator_traits_internal",
         "//absl/meta:type_traits",
     ],
 )
@@ -84,6 +87,7 @@
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/memory",
+        "//absl/meta:type_traits",
         "//absl/random",
         "//absl/types:span",
         "@googletest//:gtest",
diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt
index cdd5d14..cd7fa22 100644
--- a/absl/algorithm/CMakeLists.txt
+++ b/absl/algorithm/CMakeLists.txt
@@ -23,6 +23,7 @@
     ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::config
+    absl::core_headers
   PUBLIC
 )
 
@@ -48,7 +49,9 @@
     ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::algorithm
+    absl::hardening
     absl::config
+    absl::iterator_traits_internal
     absl::core_headers
     absl::meta
   PUBLIC
@@ -66,6 +69,7 @@
     absl::config
     absl::core_headers
     absl::memory
+    absl::meta
     absl::random_random
     absl::span
     GTest::gmock_main
diff --git a/absl/algorithm/algorithm.h b/absl/algorithm/algorithm.h
index 48f5950..4e2ebf4 100644
--- a/absl/algorithm/algorithm.h
+++ b/absl/algorithm/algorithm.h
@@ -27,6 +27,7 @@
 #include <type_traits>
 
 #include "absl/base/config.h"
+#include "absl/base/macros.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -40,8 +41,39 @@
 //
 // See the documentation for the STL <algorithm> header for more information:
 // https://en.cppreference.com/w/cpp/header/algorithm
-using std::equal;
-using std::rotate;
+
+template <class InputIt1, class InputIt2>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) {
+  return std::equal(first1, last1, first2);
+}
+
+template <class InputIt1, class InputIt2, class BinaryPredicate>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2,
+                     BinaryPredicate p) {
+  return std::equal(first1, last1, first2, p);
+}
+
+template <class InputIt1, class InputIt2>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2,
+                     InputIt2 last2) {
+  return std::equal(first1, last1, first2, last2);
+}
+
+template <class InputIt1, class InputIt2, class BinaryPredicate>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2,
+                     InputIt2 last2, BinaryPredicate p) {
+  return std::equal(first1, last1, first2, last2, p);
+}
+
+template <class ForwardIt>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr ForwardIt rotate(ForwardIt first, ForwardIt n_first, ForwardIt last) {
+  return std::rotate(first, n_first, last);
+}
 
 // linear_search()
 //
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index a823ee1..965c545 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -52,6 +52,8 @@
 
 #include "absl/algorithm/algorithm.h"
 #include "absl/base/config.h"
+#include "absl/base/internal/hardening.h"
+#include "absl/base/internal/iterator_traits.h"
 #include "absl/base/macros.h"
 #include "absl/meta/type_traits.h"
 
@@ -106,6 +108,42 @@
   return end(c);
 }
 
+// Helper to check that the `OutputRange` has enough space.
+// Only performs the check if the iterators are ForwardIterators or better.
+template <typename InputSequence, typename Size, typename OutputRange>
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 void AssertCopyNSize(InputSequence& input,
+                                                        Size n,
+                                                        OutputRange& output) {
+  using InputIter = ContainerIter<InputSequence>;
+  using OutputIter = ContainerIter<OutputRange>;
+
+  if constexpr (base_internal::IsAtLeastForwardIterator<InputIter>::value) {
+    base_internal::HardeningAssert(
+        n <= std::distance(container_algorithm_internal::c_begin(input),
+                           container_algorithm_internal::c_end(input)));
+  }
+  if constexpr (base_internal::IsAtLeastForwardIterator<OutputIter>::value) {
+    base_internal::HardeningAssert(
+        n <= std::distance(container_algorithm_internal::c_begin(output),
+                           container_algorithm_internal::c_end(output)));
+  }
+}
+
+template <typename InputSequence, typename OutputRange>
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 void AssertCopySize(InputSequence& input,
+                                                       OutputRange& output) {
+  using InputIter = ContainerIter<InputSequence>;
+  using OutputIter = ContainerIter<OutputRange>;
+  if constexpr (base_internal::IsAtLeastForwardIterator<InputIter>::value &&
+                base_internal::IsAtLeastForwardIterator<OutputIter>::value) {
+    base_internal::HardeningAssert(
+        std::distance(container_algorithm_internal::c_begin(input),
+                      container_algorithm_internal::c_end(input)) <=
+        std::distance(container_algorithm_internal::c_begin(output),
+                      container_algorithm_internal::c_end(output)));
+  }
+}
+
 template <typename T>
 struct IsUnorderedContainer : std::false_type {};
 
@@ -117,6 +155,27 @@
 struct IsUnorderedContainer<std::unordered_set<Key, Hash, KeyEqual, Allocator>>
     : std::true_type {};
 
+template <typename T, typename = void>
+struct HasBeginEnd : std::false_type {};
+
+template <typename T>
+struct HasBeginEnd<T, std::void_t<decltype(container_algorithm_internal::begin(
+                                      std::declval<T (*)()>()())),
+                                  decltype(container_algorithm_internal::end(
+                                      std::declval<T (*)()>()()))>>
+    : std::true_type {};
+
+// We don't support multidimensional arrays yet
+template <class T>
+using IsMultidimensionalArray = std::is_array<std::remove_extent_t<T>>;
+
+template <typename Iter, typename = void>
+struct IsIterator : std::false_type {};
+
+template <typename Iter>
+struct IsIterator<
+    Iter, std::void_t<typename std::iterator_traits<Iter>::iterator_category>>
+    : std::true_type {};
 }  // namespace container_algorithm_internal
 
 // PUBLIC API
@@ -521,10 +580,41 @@
 // Container-based version of the <algorithm> `std::copy()` function to copy a
 // container's elements into an iterator.
 template <typename InputSequence, typename OutputIterator>
-ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 OutputIterator
-c_copy(const InputSequence& input, OutputIterator output) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+    std::enable_if_t<container_algorithm_internal::IsIterator<
+                         absl::remove_cvref_t<OutputIterator>>::value &&
+                         !container_algorithm_internal::IsMultidimensionalArray<
+                             InputSequence>::value,
+                     std::decay_t<OutputIterator>>
+    c_copy(const InputSequence& input, OutputIterator&& output) {
   return std::copy(container_algorithm_internal::c_begin(input),
-                   container_algorithm_internal::c_end(input), output);
+                   container_algorithm_internal::c_end(input),
+                   std::forward<OutputIterator>(output));
+}
+
+// Copies elements from `input` to `output`. `absl::c_copy(input, output)` is
+// equivalent to `std::copy(std::begin(input), std::end(input),
+// std::begin(output))`.
+//
+// The `output` container must be large enough to hold all elements of `input`;
+// this function does not resize `output`.
+
+// If `std::size(input) > std::size(output)`, behavior is undefined.
+// If `std::size(output) > std::size(input)`, only `std::size(input)` elements
+// are copied, and `output` is not truncated.
+template <typename InputSequence, typename OutputRange>
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+    std::enable_if_t<container_algorithm_internal::HasBeginEnd<
+                         std::add_lvalue_reference_t<OutputRange>>::value &&
+                         !container_algorithm_internal::IsMultidimensionalArray<
+                             std::remove_reference_t<OutputRange>>::value &&
+                         !container_algorithm_internal::IsMultidimensionalArray<
+                             InputSequence>::value,
+                     void>
+    c_copy(const InputSequence& input, OutputRange&& output) {
+  container_algorithm_internal::AssertCopySize(input, output);
+  absl::c_copy(input, container_algorithm_internal::c_begin(
+                          std::forward<OutputRange>(output)));
 }
 
 // c_copy_n()
@@ -532,9 +622,40 @@
 // Container-based version of the <algorithm> `std::copy_n()` function to copy a
 // container's first N elements into an iterator.
 template <typename C, typename Size, typename OutputIterator>
-ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 OutputIterator
-c_copy_n(const C& input, Size n, OutputIterator output) {
-  return std::copy_n(container_algorithm_internal::c_begin(input), n, output);
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 std::enable_if_t<
+    container_algorithm_internal::IsIterator<
+        absl::remove_cvref_t<OutputIterator>>::value &&
+        !container_algorithm_internal::IsMultidimensionalArray<C>::value,
+    std::decay_t<OutputIterator>>
+c_copy_n(const C& input, Size n, OutputIterator&& output) {
+  return std::copy_n(container_algorithm_internal::c_begin(input), n,
+                     std::forward<OutputIterator>(output));
+}
+
+// Copies the first `n` elements from `input` to `output`.
+// `absl::c_copy_n(input, n, output)` is equivalent to
+// `std::copy_n(std::begin(input), n, std::begin(output))`.
+//
+// The `output` container must be large enough to hold N elements; this function
+// does not resize `output`.
+//
+// If `n > std::size(output)` or `n > std::size(input)`, behavior is
+// undefined.
+// If `std::size(output) > n`, only `n` elements are copied, and `output` is not
+// truncated.
+template <typename C, typename Size, typename OutputRange>
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 std::enable_if_t<
+    container_algorithm_internal::HasBeginEnd<
+        std::add_lvalue_reference_t<OutputRange>>::value &&
+        !container_algorithm_internal::IsMultidimensionalArray<
+            std::remove_reference_t<OutputRange>>::value &&
+        !container_algorithm_internal::IsMultidimensionalArray<C>::value,
+    void>
+c_copy_n(const C& input, Size n, OutputRange&& output) {
+  container_algorithm_internal::AssertCopyNSize(input, n, output);
+  absl::c_copy_n(
+      input, n,
+      container_algorithm_internal::c_begin(std::forward<OutputRange>(output)));
 }
 
 // c_copy_if()
@@ -819,8 +940,8 @@
           typename Iterator = container_algorithm_internal::ContainerIter<C>>
 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 Iterator c_rotate(C& sequence,
                                                       Iterator middle) {
-  return std::rotate(container_algorithm_internal::c_begin(sequence), middle,
-                     container_algorithm_internal::c_end(sequence));
+  return absl::rotate(container_algorithm_internal::c_begin(sequence), middle,
+                      container_algorithm_internal::c_end(sequence));
 }
 
 // c_rotate_copy()
diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc
index 8a898be..fcb8492 100644
--- a/absl/algorithm/container_test.cc
+++ b/absl/algorithm/container_test.cc
@@ -17,6 +17,7 @@
 #include <algorithm>
 #include <array>
 #include <cstddef>
+#include <forward_list>
 #include <functional>
 #include <initializer_list>
 #include <iterator>
@@ -25,6 +26,7 @@
 #include <ostream>
 #include <random>
 #include <set>
+#include <type_traits>
 #include <unordered_set>
 #include <utility>
 #include <valarray>
@@ -36,6 +38,7 @@
 #include "absl/base/config.h"
 #include "absl/base/macros.h"
 #include "absl/memory/memory.h"
+#include "absl/meta/type_traits.h"
 #include "absl/random/random.h"
 #include "absl/types/span.h"
 
@@ -712,6 +715,190 @@
   EXPECT_EQ(expected, actual);
 }
 
+TEST(MutatingTest, CopyNWithNegativeN) {
+#ifdef _LIBCPP_VERSION
+  GTEST_SKIP() << "libc++ does not handle negative counts correctly";
+#else
+  const std::vector<int> input = {1, 2, 3};
+  std::vector<int> actual = {0, 0, 0};
+  absl::c_copy_n(input, -1, actual.begin());
+  EXPECT_THAT(actual, ElementsAre(0, 0, 0));
+#endif
+}
+
+TEST(MutatingTest, CopyToContainer) {
+  const std::vector<int> input = {1, 2, 3};
+  std::vector<int> actual = {0, 0, 0, 4, 5};
+  absl::c_copy(input, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(MutatingTest, CopyNToContainer) {
+  const std::vector<int> input = {1, 2, 3, 4, 5};
+  std::vector<int> actual = {0, 0, 0, 0, 0};
+  absl::c_copy_n(input, 2, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 0, 0, 0));
+}
+
+TEST(MutatingTest, CopyNToContainerWithZeroN) {
+  const std::vector<int> input = {1, 2, 3, 4, 5};
+  std::vector<int> actual = {0, 0, 0, 0, 0};
+  absl::c_copy_n(input, 0, actual);
+  EXPECT_THAT(actual, ElementsAre(0, 0, 0, 0, 0));
+}
+
+TEST(MutatingTest, CopyNToContainerWithNegativeN) {
+#ifdef _LIBCPP_VERSION
+  GTEST_SKIP() << "libc++ does not handle negative counts correctly";
+#else
+  const std::vector<int> input = {1, 2, 3};
+  std::vector<int> actual = {0, 0, 0};
+  absl::c_copy_n(input, -1, actual);
+  EXPECT_THAT(actual, ElementsAre(0, 0, 0));
+#endif
+}
+
+TEST(MutatingTest, CopyToDifferentContainerType) {
+  const std::list<int> input = {1, 2, 3};
+  std::array<int, 5> actual = {0, 0, 0, 4, 5};
+  absl::c_copy(input, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(MutatingTest, CopyNToDifferentContainerType) {
+  const std::list<int> input = {1, 2, 3, 4, 5};
+  std::array<int, 5> actual = {0, 0, 0, 0, 0};
+  absl::c_copy_n(input, 2, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 0, 0, 0));
+}
+
+TEST(MutatingTest, CopyToCArray) {
+  const std::vector<int> input = {1, 2, 3};
+  int actual[5] = {0, 0, 0, 4, 5};
+  absl::c_copy(input, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(MutatingTest, CopyNToCArray) {
+  const std::vector<int> input = {1, 2, 3, 4, 5};
+  int actual[5] = {0, 0, 0, 0, 0};
+  absl::c_copy_n(input, 2, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 0, 0, 0));
+}
+
+TEST(MutatingTest, CopyFromCArray) {
+  const int input[5] = {1, 2, 3, 4, 5};
+  std::vector<int> actual = {0, 0, 0, 0, 0};
+  absl::c_copy(input, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(MutatingTest, CopyNFromCArray) {
+  const int input[5] = {1, 2, 3, 4, 5};
+  std::vector<int> actual = {0, 0, 0, 0, 0};
+  absl::c_copy_n(input, 2, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 0, 0, 0));
+}
+
+TEST(MutatingTest, CopyContainerWithNoSizeMethod) {
+  const std::forward_list<int> input = {1, 2, 3};
+  std::forward_list<int> actual = {0, 0, 0, 4, 5};
+  absl::c_copy(input, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST(MutatingTest, CopyNContainerWithNoSizeMethod) {
+  const std::forward_list<int> input = {1, 2, 3, 4, 5};
+  std::forward_list<int> actual = {0, 0, 0, 0, 0};
+  absl::c_copy_n(input, 2, actual);
+  EXPECT_THAT(actual, ElementsAre(1, 2, 0, 0, 0));
+}
+
+#if GTEST_HAS_DEATH_TEST
+
+bool IsHardened() {
+  bool hardened = false;
+  ABSL_HARDENING_ASSERT([&hardened]() {
+    hardened = true;
+    return true;
+  }());
+  return hardened;
+}
+
+TEST(MutatingTest, CopyToCArrayInvalidSize) {
+  const std::vector<int> input = {1, 2, 3};
+  int actual[2] = {0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy(input, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyNToCArrayInvalidSize) {
+  const std::vector<int> input = {1, 2, 3};
+  int actual[2] = {0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy_n(input, 3, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyNToCArrayNGreaterThanInput) {
+  const std::vector<int> input = {1, 2, 3};
+  int actual[4] = {0, 0, 0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy_n(input, 4, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyToContainerInvalidSize) {
+  const std::list<int> input = {1, 2, 3, 4, 5};
+  std::list<int> actual = {0, 0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy(input, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyNToContainerNGreaterThanInput) {
+  const std::vector<int> input = {1, 2, 3};
+  std::vector<int> actual = {0, 0, 0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy_n(input, 4, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyNToContainerNGreaterThanOutput) {
+  const std::vector<int> input = {1, 2, 3};
+  std::vector<int> actual = {0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy_n(input, 3, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyToForwardListInvalidSize) {
+  const std::forward_list<int> input = {1, 2, 3, 4, 5};
+  std::forward_list<int> actual = {0, 0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy(input, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyNToForwardListNGreaterThanInput) {
+  const std::forward_list<int> input = {1, 2, 3};
+  std::forward_list<int> actual = {0, 0, 0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy_n(input, 4, actual), "");
+  }
+}
+
+TEST(MutatingTest, CopyNToForwardListNGreaterThanOutput) {
+  const std::forward_list<int> input = {1, 2, 3};
+  std::forward_list<int> actual = {0, 0};
+  if (IsHardened()) {
+    EXPECT_DEATH(absl::c_copy_n(input, 3, actual), "");
+  }
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
 TEST(MutatingTest, CopyIf) {
   const std::list<int> input = {1, 2, 3};
   std::vector<int> output;
@@ -2229,4 +2416,79 @@
 #endif  // defined(ABSL_INTERNAL_CPLUSPLUS_LANG) &&
         //  ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
 
+// A type that acts as both a container and an iterator.
+struct AmbiguousType {
+  // Container requirements
+  int* begin() { return nullptr; }
+  int* end() { return nullptr; }
+
+  // Iterator requirements
+  using iterator_category = std::input_iterator_tag;
+  using value_type = int;
+  using difference_type = std::ptrdiff_t;
+  using pointer = int*;
+  using reference = int&;
+
+  int& operator*() {
+    static int x;
+    return x;
+  }
+  AmbiguousType& operator++() { return *this; }
+  AmbiguousType operator++(int) { return *this; }
+  friend bool operator==(const AmbiguousType&, const AmbiguousType&) {
+    return true;
+  }
+  friend bool operator!=(const AmbiguousType&, const AmbiguousType&) {
+    return false;
+  }
+};
+
+template <typename Container, typename Output, typename = void>
+struct CanCopy : std::false_type {};
+template <typename Container, typename Output>
+struct CanCopy<Container, Output,
+               absl::void_t<decltype(absl::c_copy(std::declval<Container>(),
+                                                  std::declval<Output>()))>>
+    : std::true_type {};
+
+template <typename Container, typename Output, typename = void>
+struct CanCopyN : std::false_type {};
+template <typename Container, typename Output>
+struct CanCopyN<Container, Output,
+                absl::void_t<decltype(absl::c_copy_n(
+                    std::declval<Container>(), std::declval<ptrdiff_t>(),
+                    std::declval<Output>()))>> : std::true_type {};
+
+TEST(CanCopyTest, CopyToMultiDimArray) {
+  static_assert(CanCopy<std::vector<int>, int (&)[10]>::value);
+  static_assert(!CanCopy<std::vector<int>, int (&)[2][2]>::value);
+  static_assert(CanCopyN<std::vector<int>, int (&)[10]>::value);
+  static_assert(!CanCopyN<std::vector<int>, int (&)[2][2]>::value);
+
+  static_assert(CanCopy<int[10], int (&)[10]>::value);
+  static_assert(!CanCopy<int[10], int (&)[2][2]>::value);
+  static_assert(CanCopyN<int[10], int (&)[10]>::value);
+  static_assert(!CanCopyN<int[10], int (&)[2][2]>::value);
+  static_assert(!CanCopy<int[2][2], int (&)[4]>::value);
+  static_assert(!CanCopy<int[2][2], int (&)[2][2]>::value);
+  static_assert(!CanCopyN<int[2][2], int (&)[4]>::value);
+  static_assert(!CanCopyN<int[2][2], int (&)[2][2]>::value);
+}
+
+TEST(CanCopyTest, BlockNonWritableIterators) {
+  using Vec = std::vector<int>;
+
+  static_assert(CanCopy<Vec, Vec::iterator>::value);
+  static_assert(CanCopy<Vec, std::back_insert_iterator<Vec>>::value);
+}
+
+TEST(CanCopyTest, AmbiguousTypeFailsToCompile) {
+  using Vec = std::vector<int>;
+  // Because AmbiguousType is both an iterator and a container,
+  // the compiler should fail to resolve the c_copy overload.
+  static_assert(!CanCopy<Vec, AmbiguousType>::value,
+                "Ambiguous types should not compile!");
+  static_assert(!CanCopyN<Vec, AmbiguousType>::value,
+                "Ambiguous types should not compile!");
+}
 }  // namespace
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 98772b1..6ade148 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -63,9 +63,6 @@
 
 cc_library(
     name = "hardening",
-    srcs = [
-        "internal/hardening.cc",
-    ],
     hdrs = [
         "internal/hardening.h",
     ],
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 582b14c..9608061 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -46,8 +46,6 @@
     hardening
   HDRS
     "internal/hardening.h"
-  SRCS
-    "internal/hardening.cc"
   DEPS
     absl::config
     absl::core_headers
diff --git a/absl/base/internal/hardening.cc b/absl/base/internal/hardening.cc
deleted file mode 100644
index 2844eec..0000000
--- a/absl/base/internal/hardening.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright 2026 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifdef _WIN32
-#include <intrin.h>
-// kFastFailInvalidArg mirrors the FAST_FAIL_INVALID_ARG macro.
-// Typically FAST_FAIL_INVALID_ARG would be imported from winnt.h
-// but winnt.h pulls in other dependencies and introduces build failures.
-constexpr unsigned int kFastFailInvalidArg = 5u;
-#endif
-
-#include "absl/base/internal/hardening.h"
-
-#include "absl/base/attributes.h"
-#include "absl/base/config.h"
-#include "absl/base/macros.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-namespace base_internal {
-
-[[noreturn]] ABSL_ATTRIBUTE_NOINLINE void HardeningAbort() {
-#ifdef _WIN32
-  __fastfail(kFastFailInvalidArg);
-#else
-  ABSL_INTERNAL_HARDENING_ABORT();
-#endif
-}
-
-}  // namespace base_internal
-
-ABSL_NAMESPACE_END
-}  // namespace absl
diff --git a/absl/base/internal/hardening.h b/absl/base/internal/hardening.h
index 6ea2833..31b25d9 100644
--- a/absl/base/internal/hardening.h
+++ b/absl/base/internal/hardening.h
@@ -23,26 +23,15 @@
 #ifndef ABSL_BASE_INTERNAL_HARDENING_H_
 #define ABSL_BASE_INTERNAL_HARDENING_H_
 
-#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/macros.h"
 #include "absl/base/options.h"
 
-#ifdef ABSL_INTERNAL_ATTRIBUTE_NO_MERGE
-#error ABSL_INTERNAL_ATTRIBUTE_NO_MERGE cannot be directly set
-#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::nomerge)
-#define ABSL_INTERNAL_ATTRIBUTE_NO_MERGE [[clang::nomerge]]
-#else
-#define ABSL_INTERNAL_ATTRIBUTE_NO_MERGE
-#endif
-
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
 namespace base_internal {
 
-[[noreturn]] ABSL_ATTRIBUTE_NOINLINE void HardeningAbort();
-
 // `HardeningAssert` performs runtime checks when Abseil Hardening is enabled,
 // even if `NDEBUG` is defined.
 //
@@ -56,7 +45,7 @@
   ABSL_ASSERT(cond);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(!cond)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -70,7 +59,7 @@
   ABSL_ASSERT(cond);
 #if (ABSL_OPTION_HARDENED == 1) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(!cond)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -80,7 +69,7 @@
   ABSL_ASSERT(val1 > val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 > val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -90,7 +79,7 @@
   ABSL_ASSERT(val1 >= val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 >= val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -100,7 +89,7 @@
   ABSL_ASSERT(val1 < val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 < val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -110,7 +99,7 @@
   ABSL_ASSERT(val1 <= val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 <= val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -124,7 +113,7 @@
   ABSL_ASSERT(!container.empty());
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(container.empty())) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -134,7 +123,7 @@
   ABSL_ASSERT(ptr != nullptr);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(ptr == nullptr)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -144,6 +133,4 @@
 ABSL_NAMESPACE_END
 }  // namespace absl
 
-#undef ABSL_INTERNAL_ATTRIBUTE_NO_MERGE
-
 #endif  // ABSL_BASE_INTERNAL_HARDENING_H_
diff --git a/absl/base/macros.h b/absl/base/macros.h
index 392b7b8..8c4a34d 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -53,6 +53,19 @@
 template <typename T, size_t N>
 auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
 }  // namespace macros_internal
+
+namespace base_internal {
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::nomerge)
+[[clang::nomerge]]  // Needed when this function is not inlined
+#endif
+[[noreturn]] inline void HardeningAbort() {
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::nomerge)
+  [[clang::nomerge]]  // Needed when this function is inlined
+#endif
+  ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL();
+  ABSL_INTERNAL_UNREACHABLE_IMPL();
+}
+}  // namespace base_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
 
@@ -122,8 +135,7 @@
 // aborts the program in release mode (when NDEBUG is defined). The
 // implementation should abort the program as quickly as possible and ideally it
 // should not be possible to ignore the abort request.
-#define ABSL_INTERNAL_HARDENING_ABORT() \
-  ((void)ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(), ABSL_INTERNAL_UNREACHABLE_IMPL())
+#define ABSL_INTERNAL_HARDENING_ABORT() ::absl::base_internal::HardeningAbort()
 
 // ABSL_HARDENING_ASSERT()
 //
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index 1fd32c5..9b52a92 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -31,6 +31,7 @@
 #define ABSL_BASE_OPTIMIZATION_H_
 
 #include <assert.h>
+#include <stdlib.h>
 
 #ifdef __cplusplus
 // Included for std::unreachable()
diff --git a/absl/base/policy_checks.h b/absl/base/policy_checks.h
index f84944c..88b5774 100644
--- a/absl/base/policy_checks.h
+++ b/absl/base/policy_checks.h
@@ -46,17 +46,17 @@
 // Toolchain Check
 // -----------------------------------------------------------------------------
 
-// We support Visual Studio 2019 (MSVC++ 16.0) and later.
+// We support Visual Studio 2022 (MSVC++ 17.0) and later.
 // This minimum will go up.
-#if defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__)
-#error "This package requires Visual Studio 2019 (MSVC++ 16.0) or higher."
+#if defined(_MSC_VER) && _MSC_VER < 1930 && !defined(__clang__)
+#error "This package requires Visual Studio 2022 (MSVC++ 17.0) or higher."
 #endif
 
 // We support GCC 7 and later.
 // This minimum will go up.
 #if defined(__GNUC__) && !defined(__clang__)
-#if __GNUC__ < 7
-#error "This package requires GCC 7 or higher."
+#if __GNUC__ < 10
+#error "This package requires GCC 10 or higher."
 #endif
 #endif
 
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index fc7633f..16a2e25 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -550,10 +550,20 @@
 size_t TypeErasedDerefAndApplyToSlotFn(const void* fn, void* slot_ptr,
                                        size_t seed) {
   const auto* f = static_cast<const Fn*>(fn);
-  const T* slot = *static_cast<const T**>(slot_ptr);
+  const T* slot = *static_cast<T**>(slot_ptr);
   return HashElement<Fn, kIsDefault>{*f, seed}(*slot);
 }
 
+// Type erased function to apply `Fn` to data inside of the `slot_ptr->first`.
+// The data is expected to have type `T`.
+template <class Fn, class T, bool kIsDefault>
+size_t TypeErasedDerefAndApplyToSlotFirstFn(const void* fn, void* slot_ptr,
+                                            size_t seed) {
+  const auto* f = static_cast<const Fn*>(fn);
+  const T* slot = *static_cast<T**>(slot_ptr);
+  return HashElement<Fn, kIsDefault>{*f, seed}(slot->first);
+}
+
 }  // namespace container_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc
index 18c8ca4..c761304 100644
--- a/absl/container/internal/hashtablez_sampler.cc
+++ b/absl/container/internal/hashtablez_sampler.cc
@@ -22,6 +22,7 @@
 #include <cstdint>
 #include <functional>
 #include <limits>
+#include <utility>
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
@@ -147,7 +148,7 @@
                            size_t value_size, uint16_t soo_capacity) {
   if (ABSL_PREDICT_FALSE(ShouldForceSampling())) {
     next_sample.next_sample = 1;
-    const int64_t old_stride = exchange(next_sample.sample_stride, 1);
+    const int64_t old_stride = std::exchange(next_sample.sample_stride, 1);
     HashtablezInfo* result = GlobalHashtablezSampler().Register(
         old_stride, inline_element_size, key_size, value_size, soo_capacity);
     return result;
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
index fa6b982..675e3a3 100644
--- a/absl/container/internal/raw_hash_set.cc
+++ b/absl/container/internal/raw_hash_set.cc
@@ -91,8 +91,8 @@
   // `min(1, RehashProbabilityConstant() / capacity())`. In order to do this,
   // we probe based on a random hash and see if the offset is less than
   // RehashProbabilityConstant().
-  return probe(capacity, absl::HashOf(RandomSeed())).offset() <
-         RehashProbabilityConstant();
+  return probe(HashtableCapacity(capacity), absl::HashOf(RandomSeed()))
+             .offset() < RehashProbabilityConstant();
 }
 
 // Find a non-deterministic hash for single group table.
@@ -185,12 +185,12 @@
 }
 
 FindInfo find_first_non_full_from_h1(const ctrl_t* ctrl, size_t h1,
-                                     size_t capacity) {
+                                     HashtableCapacity capacity) {
   auto seq = probe_h1(capacity, h1);
   if (IsEmptyOrDeleted(ctrl[seq.offset()])) {
     return {seq.offset(), /*probe_length=*/0};
   }
-  auto mask = probe_till_first_non_full_group(ctrl, seq, capacity);
+  auto mask = probe_till_first_non_full_group(ctrl, seq, capacity.capacity());
   return {seq.offset(mask.LowestBitSet()), seq.index()};
 }
 
@@ -203,7 +203,7 @@
 // slots in the same group. Such tables appear during `erase()`.
 FindInfo find_first_non_full(const CommonFields& common, size_t hash) {
   return find_first_non_full_from_h1(common.control(), H1(hash),
-                                     common.capacity());
+                                     common.capacity_impl());
 }
 
 // Same as `find_first_non_full`, but returns the mask corresponding to the
@@ -869,7 +869,7 @@
 
   const size_t soo_slot_hash =
       policy.hash_slot(policy.hash_fn(c), c.soo_data(), c.seed().seed());
-  size_t offset = probe(new_capacity, soo_slot_hash).offset();
+  size_t offset = probe(c.capacity_impl(), soo_slot_hash).offset();
   offset = offset == new_capacity ? 0 : offset;
   SanitizerPoisonMemoryRegion(new_slots, policy.slot_size * new_capacity);
   void* target_slot = SlotAddress(new_slots, offset, policy.slot_size);
@@ -1072,7 +1072,7 @@
 ABSL_ATTRIBUTE_NOINLINE size_t DecodeAndInsertImpl(
     CommonFields& c, const PolicyFunctions& __restrict policy,
     const ProbedItem* start, const ProbedItem* end, void* old_slots) {
-  const size_t new_capacity = c.capacity();
+  const HashtableCapacity new_capacity = c.capacity_impl();
 
   void* new_slots = c.slot_array();
   ctrl_t* new_ctrl = c.control();
@@ -1087,8 +1087,8 @@
     total_probe_length += target.probe_length;
     const size_t old_index = static_cast<size_t>(start->source_offset);
     const size_t new_i = target.offset;
-    ABSL_SWISSTABLE_ASSERT(old_index < new_capacity / 2);
-    ABSL_SWISSTABLE_ASSERT(new_i < new_capacity);
+    ABSL_SWISSTABLE_ASSERT(old_index < new_capacity.capacity() / 2);
+    ABSL_SWISSTABLE_ASSERT(new_i < new_capacity.capacity());
     ABSL_SWISSTABLE_ASSERT(IsEmpty(new_ctrl[new_i]));
     void* src_slot = SlotAddress(old_slots, old_index, slot_size);
     void* dst_slot = SlotAddress(new_slots, new_i, slot_size);
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 4aed15a..191b1c9 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -225,6 +225,10 @@
 #include <ranges>  // NOLINT(build/c++20)
 #endif
 
+#ifdef __BMI2__
+#include <bmi2intrin.h>
+#endif  // __BMI2__
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -301,57 +305,6 @@
 template <typename AllocType>
 void CopyAlloc(AllocType&, AllocType&, std::false_type /* propagate_alloc */) {}
 
-// The state for a probe sequence.
-//
-// Currently, the sequence is a triangular progression of the form
-//
-//   p(i) := Width * (i^2 + i)/2 + hash (mod mask + 1)
-//
-// The use of `Width` ensures that each probe step does not overlap groups;
-// the sequence effectively outputs the addresses of *groups* (although not
-// necessarily aligned to any boundary). The `Group` machinery allows us
-// to check an entire group with minimal branching.
-//
-// Wrapping around at `mask + 1` is important, but not for the obvious reason.
-// As described above, the first few entries of the control byte array
-// are mirrored at the end of the array, which `Group` will find and use
-// for selecting candidates. However, when those candidates' slots are
-// actually inspected, there are no corresponding slots for the cloned bytes,
-// so we need to make sure we've treated those offsets as "wrapping around".
-//
-// It turns out that this probe sequence visits every group exactly once if the
-// number of groups is a power of two, since (i^2+i)/2 is a bijection in
-// Z/(2^m). See https://en.wikipedia.org/wiki/Quadratic_probing
-template <size_t Width>
-class probe_seq {
- public:
-  // Creates a new probe sequence using `hash` as the initial value of the
-  // sequence and `mask` (usually the capacity of the table) as the mask to
-  // apply to each value in the progression.
-  probe_seq(size_t hash, size_t mask) {
-    ABSL_SWISSTABLE_ASSERT(((mask + 1) & mask) == 0 && "not a mask");
-    mask_ = mask;
-    offset_ = hash & mask_;
-  }
-
-  // The offset within the table, i.e., the value `p(i)` above.
-  size_t offset() const { return offset_; }
-  size_t offset(size_t i) const { return (offset_ + i) & mask_; }
-
-  void next() {
-    index_ += Width;
-    offset_ += index_;
-    offset_ &= mask_;
-  }
-  // 0-based probe index, a multiple of `Width`.
-  size_t index() const { return index_; }
-
- private:
-  size_t mask_;
-  size_t offset_;
-  size_t index_ = 0;
-};
-
 template <class ContainerKey, class Hash, class Eq>
 struct RequireUsableKey {
   template <class PassedKey, class... Args>
@@ -580,6 +533,19 @@
     return capacity_data_ <= 1;
   }
 
+  constexpr size_t mask(size_t value) const {
+#ifdef __BMI2__
+    if constexpr (StorageMode == kCapacityByLog) {
+      if constexpr (sizeof(size_t) == 8) {
+        return _bzhi_u64(value, capacity_data_);
+      } else {
+        return _bzhi_u32(value, capacity_data_);
+      }
+    }
+#endif  // __BMI2__
+    return value & capacity();
+  }
+
  private:
   // We use these sentinel capacity values in debug mode to indicate different
   // classes of bugs.
@@ -667,11 +633,10 @@
         data_(kSizeOneNoMetadata |
               (has_tried_sampling ? kSooHasTriedSamplingMask : 0)) {}
 
-  HashtableCapacity maybe_invalid_capacity() const {
+  HashtableCapacity capacity() const {
     return HashtableCapacity::FromRawData(capacity_internal_);
   }
-  size_t capacity() const { return maybe_invalid_capacity().capacity(); }
-  bool is_small() const { return maybe_invalid_capacity().is_small(); }
+  bool is_small() const { return capacity().is_small(); }
 
   void set_capacity(HashtableCapacity c) { capacity_internal_ = c.ToRawData(); }
   void set_capacity(size_t c) { set_capacity(HashtableCapacity(c)); }
@@ -1251,10 +1216,16 @@
   }
   void set_no_seed_for_testing() { inline_data_.set_no_seed_for_testing(); }
 
-  // The total number of available slots.
-  size_t capacity() const { return inline_data_.capacity(); }
+  HashtableCapacity capacity_impl() const {
+    HashtableCapacity cap = inline_data_.capacity();
+    ABSL_SWISSTABLE_ASSERT(cap.IsValid());
+    return cap;
+  }
+  size_t capacity() const { return capacity_impl().capacity(); }
+  // We have a separate alias for callsites in which the capacity may be
+  // invalid.
   HashtableCapacity maybe_invalid_capacity() const {
-    return inline_data_.maybe_invalid_capacity();
+    return inline_data_.capacity();
   }
   void set_capacity(HashtableCapacity c) { inline_data_.set_capacity(c); }
   void set_capacity(size_t c) {
@@ -1408,6 +1379,26 @@
 #endif
 }
 
+// Dereferences `ptr`. The function is named in order to provide a helpful error
+// message when users see crashing stack traces. Note that this function is not
+// guaranteed to crash when `ptr` is invalid if sanitizer mode is not enabled.
+template <typename T>
+T CrashIfIteratorIsInvalid(const T* ptr) {
+  // If the following line(s) crash, then it's likely that `ptr` is from a
+  // backing array that has been deallocated. If you see a crash here, it likely
+  // means that you are comparing an invalid iterator from a table that has
+  // rehashed, moved, or been destroyed. In such cases, it is often helpful to
+  // reproduce the issue with --config=asan and (assuming there's a crash here)
+  // examine the corresponding deallocation stack trace.
+  T ret = *ptr;
+  // Force a read with inline asm to make sure that a crash happens here, rather
+  // than later when the value is used.
+#ifdef __clang__
+  asm("" : "+r"(ret));
+#endif
+  return ret;
+}
+
 inline void AssertIsFull(const ctrl_t* ctrl, GenerationType generation,
                          const GenerationType* generation_ptr,
                          const char* operation) {
@@ -1425,20 +1416,21 @@
                  operation);
   }
   if (SwisstableGenerationsEnabled()) {
-    if (ABSL_PREDICT_FALSE(generation != *generation_ptr)) {
+    if (ABSL_PREDICT_FALSE(generation !=
+                           CrashIfIteratorIsInvalid(generation_ptr))) {
       ABSL_RAW_LOG(FATAL,
                    "%s called on invalid iterator. The table could have "
                    "rehashed or moved since this iterator was initialized.",
                    operation);
     }
-    if (ABSL_PREDICT_FALSE(!IsFull(*ctrl))) {
+    if (ABSL_PREDICT_FALSE(!IsFull(CrashIfIteratorIsInvalid(ctrl)))) {
       ABSL_RAW_LOG(
           FATAL,
           "%s called on invalid iterator. The element was likely erased.",
           operation);
     }
   } else {
-    if (ABSL_PREDICT_FALSE(!IsFull(*ctrl))) {
+    if (ABSL_PREDICT_FALSE(!IsFull(CrashIfIteratorIsInvalid(ctrl)))) {
       ABSL_RAW_LOG(
           FATAL,
           "%s called on invalid iterator. The element might have been erased "
@@ -1454,20 +1446,15 @@
                                        GenerationType generation,
                                        const GenerationType* generation_ptr) {
   if (!SwisstableDebugEnabled()) return;
-  const bool ctrl_is_valid_for_comparison = [ctrl]() {
-    if (ctrl == nullptr) return true;
-    if (ctrl == DefaultIterControl()) return true;
-    // Note: if the following line crashes, then it's likely that `ctrl` is from
-    // a backing array that has been deallocated. If you see a crash here, it
-    // likely means that you are comparing an invalid iterator from a table that
-    // has rehashed, moved, or been destroyed.
-    return IsFull(*ctrl);
-  }();
+  const bool ctrl_is_valid_for_comparison =
+      ctrl == nullptr || ctrl == DefaultIterControl() ||
+      IsFull(CrashIfIteratorIsInvalid(ctrl));
   if (SwisstableGenerationsEnabled()) {
-    if (ABSL_PREDICT_FALSE(generation != *generation_ptr)) {
+    if (ABSL_PREDICT_FALSE(generation !=
+                           CrashIfIteratorIsInvalid(generation_ptr))) {
       // Note: in the case of a rehash, we would expect to see a sanitizer crash
-      // above when `ctrl` is dereferenced so this assertion will only catch
-      // moved table cases, unless we're using a custom allocator that does not
+      // in CrashIfIteratorIsInvalid so this assertion will only catch moved
+      // table cases, unless we're using a custom allocator that does not
       // deallocate the old backing array (e.g. an arena allocator).
       ABSL_RAW_LOG(
           FATAL,
@@ -1576,15 +1563,64 @@
   return capacity <= Group::kWidth;
 }
 
+// The state for a probe sequence.
+//
+// Currently, the sequence is a triangular progression of the form
+//
+//   p(i) := Width * (i^2 + i)/2 + hash (mod mask + 1)
+//
+// The use of `Width` ensures that each probe step does not overlap groups;
+// the sequence effectively outputs the addresses of *groups* (although not
+// necessarily aligned to any boundary). The `Group` machinery allows us
+// to check an entire group with minimal branching.
+//
+// Wrapping around at `mask + 1` is important, but not for the obvious reason.
+// As described above, the first few entries of the control byte array
+// are mirrored at the end of the array, which `Group` will find and use
+// for selecting candidates. However, when those candidates' slots are
+// actually inspected, there are no corresponding slots for the cloned bytes,
+// so we need to make sure we've treated those offsets as "wrapping around".
+//
+// It turns out that this probe sequence visits every group exactly once if the
+// number of groups is a power of two, since (i^2+i)/2 is a bijection in
+// Z/(2^m). See https://en.wikipedia.org/wiki/Quadratic_probing
+template <size_t Width>
+class probe_seq {
+ public:
+  // Creates a new probe sequence using `hash` as the initial value of the
+  // sequence and `capacity` as the mask to apply to each value in the
+  // progression.
+  probe_seq(HashtableCapacity capacity, size_t hash)
+      : capacity_(capacity), offset_(capacity.mask(hash)) {}
+
+  // The offset within the table, i.e., the value `p(i)` above.
+  size_t offset() const { return offset_; }
+  size_t offset(size_t i) const { return capacity_.mask(offset_ + i); }
+
+  void next() {
+    index_ += Width;
+    offset_ += index_;
+    offset_ = capacity_.mask(offset_);
+  }
+  // 0-based probe index, a multiple of `Width`.
+  size_t index() const { return index_; }
+
+ private:
+  HashtableCapacity capacity_;
+  size_t offset_;
+  size_t index_ = 0;
+};
+
 // Begins a probing operation on `common.control`, using `hash`.
-inline probe_seq<Group::kWidth> probe_h1(size_t capacity, size_t h1) {
-  return probe_seq<Group::kWidth>(h1, capacity);
+inline probe_seq<Group::kWidth> probe_h1(HashtableCapacity capacity,
+                                         size_t h1) {
+  return probe_seq<Group::kWidth>(capacity, h1);
 }
-inline probe_seq<Group::kWidth> probe(size_t capacity, size_t hash) {
+inline probe_seq<Group::kWidth> probe(HashtableCapacity capacity, size_t hash) {
   return probe_h1(capacity, H1(hash));
 }
 inline probe_seq<Group::kWidth> probe(const CommonFields& common, size_t hash) {
-  return probe(common.capacity(), hash);
+  return probe(common.capacity_impl(), hash);
 }
 
 constexpr size_t kProbedElementIndexSentinel = ~size_t{};
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 0edf6bf..3f81f26 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -338,7 +338,8 @@
 }
 
 TEST(Util, probe_seq) {
-  probe_seq<16> seq(0, 127);
+  HashtableCapacity capacity(127);
+  probe_seq<16> seq(capacity, /*hash=*/0);
   auto gen = [&]() {
     size_t res = seq.offset();
     seq.next();
@@ -347,7 +348,7 @@
   std::vector<size_t> offsets(8);
   std::generate_n(offsets.begin(), 8, gen);
   EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
-  seq = probe_seq<16>(128, 127);
+  seq = probe_seq<16>(capacity, /*hash=*/128);
   std::generate_n(offsets.begin(), 8, gen);
   EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64));
 }
@@ -421,24 +422,24 @@
   using Capacity = HashtableCapacityImpl<kMode>;
 
   InlineData data(Capacity(0), no_seed_empty_tag_t{});
-  EXPECT_EQ(data.capacity(), 0);
+  EXPECT_EQ(data.capacity().capacity(), 0);
   EXPECT_EQ(data.size(), 0);
   EXPECT_TRUE(data.empty());
 
   for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
     data.set_capacity(cap);
-    ASSERT_EQ(data.capacity(), cap);
+    ASSERT_EQ(data.capacity().capacity(), cap);
   }
 
   // Test overload from `Capacity` object.
   for (size_t i = 0, cap = 0; i < 20; ++i, cap = NextCapacity(cap)) {
     data.set_capacity(Capacity(cap));
-    ASSERT_EQ(data.capacity(), cap);
+    ASSERT_EQ(data.capacity().capacity(), cap);
   }
 
   auto reentrance = Capacity::CreateReentrance();
   data.set_capacity(reentrance);
-  EXPECT_TRUE(data.maybe_invalid_capacity().IsReentrance());
+  EXPECT_TRUE(data.capacity().IsReentrance());
 }
 
 TYPED_TEST(HashtableDataTest, HashtableInlineDataSize) {
@@ -502,7 +503,7 @@
   {
     InlineData data_soo(Capacity(1), full_soo_tag_t{},
                         /*has_tried_sampling=*/true);
-    EXPECT_EQ(data_soo.capacity(), 1);
+    EXPECT_EQ(data_soo.capacity().capacity(), 1);
     EXPECT_EQ(data_soo.size(), 1);
     EXPECT_TRUE(data_soo.soo_has_tried_sampling());
   }
@@ -510,7 +511,7 @@
   {
     InlineData data_soo(Capacity(1), full_soo_tag_t{},
                         /*has_tried_sampling=*/false);
-    EXPECT_EQ(data_soo.capacity(), 1);
+    EXPECT_EQ(data_soo.capacity().capacity(), 1);
     EXPECT_EQ(data_soo.size(), 1);
     EXPECT_FALSE(data_soo.soo_has_tried_sampling());
   }
@@ -2921,12 +2922,11 @@
   // the control is static constant.
 }
 
-// Invalid iterator use can trigger use-after-free in asan/hwasan,
-// use-of-uninitialized-value in msan, or invalidated iterator assertions.
+// Invalid iterator use can trigger crashes or invalidated iterator assertions.
 testing::Matcher<const std::string&> InvalidIteratorMatcher() {
   return AnyOf(HasSubstr("invalidated iterator"), HasSubstr("Invalid iterator"),
-               HasSubstr("invalid iterator"), HasSubstr("use-after-free"),
-               HasSubstr("use-of-uninitialized-value"));
+               HasSubstr("invalid iterator"),
+               HasSubstr("CrashIfIteratorIsInvalid"));
 }
 
 TYPED_TEST(SooTest, IteratorInvalidAssertsEqualityOperator) {
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h
index e913005..a58680a 100644
--- a/absl/container/node_hash_map.h
+++ b/absl/container/node_hash_map.h
@@ -681,7 +681,8 @@
   template <class Hash, bool kIsDefault>
   static constexpr HashSlotFn get_hash_slot_fn() {
     return memory_internal::IsLayoutCompatible<Key, Value>::value
-               ? &TypeErasedDerefAndApplyToSlotFn<Hash, Key, kIsDefault>
+               ? &TypeErasedDerefAndApplyToSlotFirstFn<Hash, value_type,
+                                                       kIsDefault>
                : nullptr;
   }
 };
diff --git a/absl/crc/internal/crc_x86_arm_combined.cc b/absl/crc/internal/crc_x86_arm_combined.cc
index b81490f..9e70b92 100644
--- a/absl/crc/internal/crc_x86_arm_combined.cc
+++ b/absl/crc/internal/crc_x86_arm_combined.cc
@@ -746,8 +746,10 @@
 CRCImpl* TryNewCRC32AcceleratedX86ARMCombined() {
   CpuType type = GetCpuType();
   switch (type) {
-    case CpuType::kIntelHaswell:
     case CpuType::kAmdRome:
+      return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
+          3, 0, 0, CutoffStrategy::Fold3>();
+    case CpuType::kIntelHaswell:
     case CpuType::kAmdNaples:
       return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
           3, 1, 0, CutoffStrategy::Fold3>();
diff --git a/absl/debugging/internal/stacktrace_generic-inl.inc b/absl/debugging/internal/stacktrace_generic-inl.inc
index e7a11fc..c94bf3e 100644
--- a/absl/debugging/internal/stacktrace_generic-inl.inc
+++ b/absl/debugging/internal/stacktrace_generic-inl.inc
@@ -71,13 +71,20 @@
 
   size = backtrace(stack, kStackLength);
   skip_count++;  // we want to skip the current frame as well
-  int result_count = size - skip_count;
-  if (result_count < 0)
-    result_count = 0;
-  if (result_count > max_depth)
-    result_count = max_depth;
-  for (int i = 0; i < result_count; i++)
-    result[i] = stack[i + skip_count];
+
+  int num_frames = size - skip_count;
+  if (num_frames < 0) num_frames = 0;
+  if (num_frames > max_depth) num_frames = max_depth;
+
+  int result_count = 0;
+  for (int i = 0; i < num_frames; i++) {
+    int stack_index = i + skip_count;
+    // Follow x86 and stop if the return address is null (end of stack).
+    if (stack[stack_index] == nullptr) {
+      break;
+    }
+    result[result_count++] = stack[stack_index];
+  }
 
   if (IS_STACK_FRAMES) {
     // No implementation for finding out the stack frames yet.
diff --git a/absl/log/internal/BUILD.bazel b/absl/log/internal/BUILD.bazel
index ebacbc1..6995b26 100644
--- a/absl/log/internal/BUILD.bazel
+++ b/absl/log/internal/BUILD.bazel
@@ -122,6 +122,11 @@
     hdrs = ["flags.h"],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
+    visibility = [
+        ":internal_users",
+        "//absl:friends",
+        "//absl/status:__pkg__",
+    ],
     deps = [
         "//absl/flags:flag",
     ],
@@ -467,6 +472,7 @@
     visibility = [
         "//absl:friends",
         "//absl/log:__subpackages__",
+        "//absl/status:__pkg__",
     ],
     deps = [
         ":fnmatch",
diff --git a/absl/log/internal/log_message.cc b/absl/log/internal/log_message.cc
index d253b0c..4acd503 100644
--- a/absl/log/internal/log_message.cc
+++ b/absl/log/internal/log_message.cc
@@ -721,7 +721,7 @@
   }
 
   // Write the string, truncating if necessary.
-  if (!EncodeStringTruncate(ValueTag::kString, str, &encoded_remaining_copy)) {
+  if (!EncodeStringTruncate(tag_value, str, &encoded_remaining_copy)) {
     // The length of the string itself did not fit; zero `encoded_remaining()`
     // so the value is not encoded at all.
     data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
diff --git a/absl/status/BUILD.bazel b/absl/status/BUILD.bazel
index dce316b..a8e45cb 100644
--- a/absl/status/BUILD.bazel
+++ b/absl/status/BUILD.bazel
@@ -71,6 +71,7 @@
         "//absl/strings:cord",
         "//absl/strings:str_format",
         "//absl/types:optional",
+        "//absl/types:optional_ref",
         "//absl/types:source_location",
         "//absl/types:span",
     ],
@@ -166,6 +167,78 @@
 )
 
 cc_library(
+    name = "status_builder",
+    srcs = ["status_builder.cc"],
+    hdrs = ["status_builder.h"],
+    copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":status",
+        "//absl/base:config",
+        "//absl/base:core_headers",
+        "//absl/base:log_severity",
+        "//absl/strings",
+        "//absl/strings:cord",
+        "//absl/strings:internal",
+        "//absl/strings:stringify_stream",
+        "//absl/time",
+        "//absl/types:source_location",
+    ],
+)
+
+cc_test(
+    name = "status_builder_test",
+    srcs = ["status_builder_test.cc"],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":status",
+        ":status_builder",
+        ":status_matchers",
+        ":statusor",
+        "//absl/base:config",
+        "//absl/log",
+        "//absl/log:flags",
+        "//absl/log:log_entry",
+        "//absl/log:log_sink",
+        "//absl/strings",
+        "//absl/types:source_location",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
+    ],
+)
+
+cc_library(
+    name = "status_macros",
+    hdrs = ["status_macros.h"],
+    deps = [
+        ":status",
+        ":status_builder",
+        ":statusor",
+        "//absl/base:config",
+        "//absl/base:core_headers",
+        "//absl/types:source_location",
+    ],
+)
+
+cc_test(
+    name = "status_macros_test",
+    size = "small",
+    srcs = ["status_macros_test.cc"],
+    deps = [
+        ":status",
+        ":status_builder",
+        ":status_macros",
+        ":statusor",
+        "//absl/base:core_headers",
+        "//absl/strings:string_view",
+        "//absl/types:source_location",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
+    ],
+)
+
+cc_library(
     name = "status_matchers",
     testonly = 1,
     srcs = [
diff --git a/absl/status/CMakeLists.txt b/absl/status/CMakeLists.txt
index 8d519a5..90d4baf 100644
--- a/absl/status/CMakeLists.txt
+++ b/absl/status/CMakeLists.txt
@@ -35,6 +35,7 @@
     absl::core_headers
     absl::function_ref
     absl::inlined_vector
+    absl::internal_optional_ref
     absl::leak_check
     absl::memory
     absl::no_destructor
@@ -111,6 +112,91 @@
 
 absl_cc_library(
   NAME
+    status_builder
+  HDRS
+    "status_builder.h"
+  SRCS
+    "status_builder.cc"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  DEPS
+    absl::config
+    absl::cord
+    absl::core_headers
+    absl::nullability
+    absl::optional
+    absl::source_location
+    absl::span
+    absl::status
+    absl::strings
+    absl::time
+  PUBLIC
+)
+
+absl_cc_test(
+  NAME
+    status_builder_test
+  SRCS
+   "status_builder_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
+  DEPS
+    absl::core_headers
+    absl::flags
+    GTest::gmock_main
+    absl::log
+    absl::log_entry
+    absl::log_flags
+    absl::log_internal_flags
+    absl::log_severity
+    absl::log_sink
+    absl::scoped_mock_log
+    absl::source_location
+    absl::span
+    absl::status
+    absl::statusor
+    absl::status_builder
+    absl::status_matchers
+    absl::strings
+    absl::time
+)
+
+absl_cc_library(
+  NAME
+    status_macros
+  HDRS
+    "status_macros.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  DEPS
+    absl::core_headers
+    absl::source_location
+    absl::status
+    absl::status_builder
+    absl::statusor
+  PUBLIC
+)
+
+absl_cc_test(
+  NAME
+    status_macros_test
+  SRCS
+   "status_macros_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
+  DEPS
+    absl::core_headers
+    absl::source_location
+    absl::status
+    absl::status_builder
+    absl::status_macros
+    absl::statusor
+    absl::string_view
+    GTest::gmock_main
+)
+
+absl_cc_library(
+  NAME
     status_matchers
   HDRS
     "status_matchers.h"
diff --git a/absl/status/internal/status_internal.cc b/absl/status/internal/status_internal.cc
index 1397de7..f58519b 100644
--- a/absl/status/internal/status_internal.cc
+++ b/absl/status/internal/status_internal.cc
@@ -42,6 +42,7 @@
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_split.h"
 #include "absl/strings/string_view.h"
+#include "absl/types/optional_ref.h"
 #include "absl/types/source_location.h"
 #include "absl/types/span.h"
 
@@ -211,9 +212,12 @@
   return true;
 }
 
-StatusRep* absl_nonnull StatusRep::CloneAndUnref() const {
+StatusRep* absl_nonnull StatusRep::Clone(
+    absl::optional_ref<absl::string_view> new_message, bool include_payloads,
+    bool include_source_locations) const {
   // Optimization: no need to create a clone if we already have a refcount of 1.
-  if (ref_.load(std::memory_order_acquire) == 1) {
+  if (ref_.load(std::memory_order_acquire) == 1 && !new_message.has_value() &&
+      include_payloads && include_source_locations) {
     // All StatusRep instances are heap allocated and mutable, therefore this
     // const_cast will never cast away const from a stack instance.
     //
@@ -222,12 +226,30 @@
     return const_cast<StatusRep*>(this);
   }
   std::unique_ptr<status_internal::Payloads> payloads;
-  if (payloads_) {
+  if (include_payloads && payloads_) {
     payloads = std::make_unique<status_internal::Payloads>(*payloads_);
   }
-  auto* new_rep = new StatusRep(code_, message_, std::move(payloads));
-  new_rep->source_locations_ = source_locations_;
-  Unref();
+  auto* new_rep =
+      new StatusRep(code_, new_message.value_or(message_), std::move(payloads));
+  if (include_source_locations) {
+    new_rep->source_locations_ = source_locations_;
+  }
+  return new_rep;
+}
+
+StatusRep* absl_nonnull StatusRep::CloneAndUnref() const {
+  return CloneAndUnref(std::nullopt, true, true);
+}
+
+StatusRep* absl_nonnull StatusRep::CloneAndUnref(
+    absl::optional_ref<absl::string_view> new_message, bool include_payloads,
+    bool include_source_locations) const {
+  StatusRep* new_rep =
+      Clone(new_message, /*include_payloads=*/include_payloads,
+            /*include_source_locations=*/include_source_locations);
+  if (new_rep != this) {
+    Unref();
+  }
   return new_rep;
 }
 
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h
index d5aa285..2f615e7 100644
--- a/absl/status/internal/status_internal.h
+++ b/absl/status/internal/status_internal.h
@@ -29,6 +29,7 @@
 #include "absl/strings/cord.h"
 #include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
+#include "absl/types/optional_ref.h"
 #include "absl/types/source_location.h"
 #include "absl/types/span.h"
 
@@ -62,6 +63,7 @@
 namespace status_internal {
 #ifndef SWIG
 class StatusPrivateAccessor;
+class StatusPrivateAccessorForStatusBuilder;
 #endif  // !SWIG
 
 // Container for status payloads.
@@ -112,7 +114,17 @@
 
   // Returns an equivalent heap allocated StatusRep with refcount 1.
   //
-  // `this` is not safe to be used after calling as it may have been deleted.
+  // If `new_message` is provided, the message will be replaced with the new
+  // message.
+  StatusRep* absl_nonnull Clone(
+      absl::optional_ref<absl::string_view> new_message, bool include_payloads,
+      bool include_source_locations) const;
+
+  // Same as Clone(), but also removes a reference to `this`. `this` is not safe
+  // to be used after calling as it may have been deleted.
+  StatusRep* absl_nonnull CloneAndUnref(
+      absl::optional_ref<absl::string_view> new_message, bool include_payloads,
+      bool include_source_locations) const;
   StatusRep* absl_nonnull CloneAndUnref() const;
 
  private:
diff --git a/absl/status/status.h b/absl/status/status.h
index a2cd834..88486d3 100644
--- a/absl/status/status.h
+++ b/absl/status/status.h
@@ -698,6 +698,7 @@
   static Status MakeNonOkStatusWithOkCode(absl::string_view message);
 
   friend class absl::status_internal::StatusPrivateAccessor;
+  friend class absl::status_internal::StatusPrivateAccessorForStatusBuilder;
 #endif  // !SWIG
 
   // Creates a status in the canonical error space with the specified
diff --git a/absl/status/status_builder.cc b/absl/status/status_builder.cc
new file mode 100644
index 0000000..929dead
--- /dev/null
+++ b/absl/status/status_builder.cc
@@ -0,0 +1,196 @@
+// Copyright 2026 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/status/status_builder.h"
+
+#include <cstdint>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/macros.h"
+#include "absl/status/status.h"
+#include "absl/strings/cord.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+#include "absl/types/source_location.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+void StatusBuilder::Destroy(std::unique_ptr<Rep>) {
+  // nothing to do. The unique_ptr will do the cleanup.
+}
+
+// These constructors are not-inlined and defined in the .cc file to reduce
+// binary size. See cl/354351433 for a quantification.
+StatusBuilder::StatusBuilder() {}
+
+StatusBuilder::StatusBuilder(const absl::Status& original_status,
+                             absl::SourceLocation location)
+    : loc_(location), rep_(InitRep(original_status)) {}
+
+StatusBuilder::operator absl::Status() const& {
+  if (rep_ == nullptr) return absl::Status();
+  return CreateStatusAndConditionallyLog(loc_, std::make_unique<Rep>(*rep_));
+}
+
+StatusBuilder::Rep::Rep(const absl::Status& s) : status(s) {}
+StatusBuilder::Rep::Rep(absl::Status&& s) : status(std::move(s)) {}
+StatusBuilder::Rep::~Rep() {}
+
+StatusBuilder::Rep* StatusBuilder::InitRepImpl(absl::Status s) {
+  if (s.ok()) {
+    return nullptr;
+  } else {
+    return new Rep(std::move(s));
+  }
+}
+
+StatusBuilder::Rep::Rep(const Rep& r)
+    : status(r.status),
+      logging_mode(r.logging_mode),
+      log_severity(r.log_severity),
+      verbose_level(r.verbose_level),
+      n(r.n),
+      period(r.period),
+      stream_message(r.stream_message),
+      sink(r.sink),
+      message_join_style(r.message_join_style),
+      should_log_stack_trace(r.should_log_stack_trace),
+      also_send_to_log(r.also_send_to_log) {
+  if (r.stream.has_value()) {
+    InitStream();
+  }
+}
+
+void StatusBuilder::Rep::InitStream() { stream.emplace(stream_message); }
+
+bool StatusBuilder::HasPayload() const {
+  static constexpr absl::string_view kMessageSetUrl =
+      "type.googleapis.com/util.MessageSetPayload";
+  return rep_ != nullptr && rep_->status.GetPayload(kMessageSetUrl).has_value();
+}
+
+ABSL_ATTRIBUTE_WEAK StatusBuilder& StatusBuilder::SetCode(
+    absl::StatusCode code) & {
+  if (rep_ == nullptr) {
+    rep_ = std::make_unique<StatusBuilder::Rep>(
+        absl::Status(code, absl::string_view(), absl::SourceLocation()));
+  } else {
+    absl::Status status(code, absl::string_view(), absl::SourceLocation());
+    rep_->status.ForEachPayload(
+        [&status](absl::string_view type_url, const absl::Cord& payload) {
+          status.SetPayload(type_url, payload);
+        });
+    rep_->status = std::move(status);
+  }
+  return *this;
+}
+
+ABSL_ATTRIBUTE_WEAK void AbslInternalSetErrorCode(StatusBuilder& builder,
+                                                  absl::StatusCode code) {
+  builder.SetCode(code);
+}
+
+class status_internal::StatusPrivateAccessorForStatusBuilder {
+ public:
+  static absl::Status SetMessage(const absl::Status& status,
+                                 absl::string_view message) {
+    ABSL_ASSERT(!status.ok());
+
+    if (message.empty()) {
+      return absl::Status(status.code(), message, absl::SourceLocation());
+    }
+
+    using StatusRep =
+        std::remove_cv_t<std::remove_pointer_t<decltype(Status::RepToPointer(
+            std::declval<uintptr_t>()))>>;
+    StatusRep* rep;
+    if (Status::IsInlined(status.rep_)) {
+      rep = new StatusRep(Status::InlinedRepToCode(status.rep_), message,
+                          nullptr);
+    } else {
+      rep = Status::RepToPointer(status.rep_)->Clone(message, true, true);
+    }
+    return absl::Status(Status::PointerToRep(rep));
+  }
+
+  static absl::Status JoinMessageToStatus(absl::Status s, absl::string_view msg,
+                                          MessageJoinStyle style) {
+    if (s.ok() || msg.empty()) return s;
+    const absl::string_view original_message = s.message();
+    switch (style) {
+      case MessageJoinStyle::kAnnotate: {
+        std::string annotated;
+        if (!original_message.empty()) {
+          absl::StrAppend(&annotated, original_message, "; ", msg);
+          msg = annotated;
+        }
+        return SetMessage(s, msg);
+      }
+      case MessageJoinStyle::kPrepend:
+        return SetMessage(s, absl::StrCat(msg, original_message));
+      case MessageJoinStyle::kAppend:
+        return SetMessage(s, absl::StrCat(original_message, msg));
+      default:
+        return absl::InternalError("Unknown MessageJoinStyle");
+    }
+  }
+};
+
+ABSL_ATTRIBUTE_WEAK std::string StatusBuilder::CurrentStackTrace() {
+  return std::string();
+}
+
+ABSL_ATTRIBUTE_WEAK absl::Status StatusBuilder::CreateStatusAndConditionallyLog(
+    absl::SourceLocation loc, std::unique_ptr<Rep> rep) {
+  if (rep == nullptr) return absl::OkStatus();
+  absl::Status result = status_internal::StatusPrivateAccessorForStatusBuilder::
+      JoinMessageToStatus(std::move(rep->status), rep->stream_message,
+                          rep->message_join_style);
+  // Passing in the `loc` last to ensure the sequence of the source locations.
+  result.AddSourceLocation(loc);
+  return result;
+}
+
+ABSL_ATTRIBUTE_WEAK std::string StatusBuilder::ToString() const {
+  if (rep_ == nullptr) {
+    return absl::OkStatus().ToString();
+  }
+
+  return status_internal::StatusPrivateAccessorForStatusBuilder::
+      JoinMessageToStatus(rep_->status, rep_->stream_message,
+                          rep_->message_join_style)
+          .WithSourceLocation(loc_)
+          .ToString();
+}
+
+ABSL_ATTRIBUTE_WEAK std::ostream& operator<<(std::ostream& os,
+                                             const StatusBuilder& builder) {
+  return os << static_cast<absl::Status>(builder);
+}
+
+ABSL_ATTRIBUTE_WEAK std::ostream& operator<<(std::ostream& os,
+                                             StatusBuilder&& builder) {
+  return os << static_cast<absl::Status>(std::move(builder));
+}
+
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/absl/status/status_builder.h b/absl/status/status_builder.h
new file mode 100644
index 0000000..60b7562
--- /dev/null
+++ b/absl/status/status_builder.h
@@ -0,0 +1,978 @@
+// Copyright 2026 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: status_builder.h
+// -----------------------------------------------------------------------------
+
+#ifndef ABSL_STATUS_STATUS_BUILDER_H_
+#define ABSL_STATUS_STATUS_BUILDER_H_
+
+#include <memory>
+#include <optional>
+#include <ostream>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/log_severity.h"
+#include "absl/base/optimization.h"
+#include "absl/status/status.h"
+#include "absl/strings/cord.h"
+#include "absl/strings/internal/ostringstream.h"
+#include "absl/strings/internal/stringify_stream.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+#include "absl/types/source_location.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+class LogSink;
+class StatusBuilder;
+
+namespace status_internal {
+
+// StatusBuilder's operator<< overloads use an AbslStringifyStream to allow us
+// to use AbslStringify. This wraps (but does not own) an OStringStream, which
+// we use for speed. We bundle them together in Stream here, partly for
+// convenience in StatusBuilder's implementation, and partly to help make sure
+// their lifetimes are managed correctly.
+class Stream {
+ public:
+  explicit Stream(std::string& message)
+      : ostringstream_(&message), absl_stringify_stream_(ostringstream_) {}
+
+  template <typename T>
+  friend Stream& operator<<(Stream& stream, const T& t) {
+    stream.absl_stringify_stream_ << t;
+    return stream;
+  }
+
+ private:
+  absl::strings_internal::OStringStream ostringstream_;
+  absl::strings_internal::StringifyStream absl_stringify_stream_;
+};
+
+// StatusBuilder::With() adaptors can be classified as either "pure policy" or
+// "terminal". Terminal adaptors are a mix of "side effect" or "conversion".
+// We differentiate between these types by the functor's return type.
+//
+// This is currently for analysis only, as part of an ongoing LSC investigation.
+template <typename Fn, typename Arg, typename Expected>
+inline constexpr bool kResultMatches =
+    std::is_same_v<std::decay_t<std::invoke_result_t<Fn, Arg>>, Expected>;
+
+template <typename Adaptor, typename Builder>
+using PurePolicy =
+    std::enable_if_t<kResultMatches<Adaptor, Builder, StatusBuilder>,
+                     std::invoke_result_t<Adaptor, Builder>>;
+
+template <typename Adaptor, typename Builder>
+using SideEffect =
+    std::enable_if_t<kResultMatches<Adaptor, Builder, absl::Status>,
+                     std::invoke_result_t<Adaptor, Builder>>;
+
+template <typename Adaptor, typename Builder>
+using Conversion =
+    std::enable_if_t<!kResultMatches<Adaptor, Builder, StatusBuilder> &&
+                         !kResultMatches<Adaptor, Builder, absl::Status>,
+                     std::invoke_result_t<Adaptor, Builder>>;
+
+class StatusBuilderPrivateAccessor;
+
+}  // namespace status_internal
+
+// Internal argument-dependent lookup extension point for StatusBuilder.
+// Necessary for allowing StatusBuilder to be open-sourced into Abseil without
+// introducing hard dependencies on non-canonical error spaces or protobuf.
+//
+// What we would have preferred here is to just leave
+// StatusBuilder::SetErrorCode() undeclared for OSS users, but defined for
+// internal users. However, C++ doesn't provide a great way to do that directly,
+// since merely omitting a definition still leaves it declared and thus
+// accessible.
+//
+// We therefore use this ADL extension point as the closest moral equivalent:
+// this allows use to define a simple shell for the method in OSS, but to
+// prevent its actual usage (via SFINAE) unless this extension point is also
+// defined, which is only the case in our internal libraries.
+void AbslInternalSetErrorCode(StatusBuilder&, absl::StatusCode);
+
+// Specifies how to join the error message in the original status and any
+// additional message that has been streamed into the builder.
+enum class MessageJoinStyle {
+  kAnnotate,
+  kAppend,
+  kPrepend,
+};
+
+// Creates a status based on an original_status, but enriched with additional
+// information.  The builder implicitly converts to Status and StatusOr<T>
+// allowing for it to be returned directly.
+//
+//   StatusBuilder builder(original);
+//   builder.SetPayload(proto);
+//   builder << "info about error";
+//   return builder;
+//
+// It provides method chaining to simplify typical usage:
+//
+//   return StatusBuilder(original)
+//       .Log(absl::LogSeverity::kWarning) << "oh no!";
+//
+// In more detail:
+// - When the original status is OK, all methods become no-ops and nothing will
+//   be logged.
+// - Messages streamed into the status builder are collected into a single
+//   additional message string.
+// - The original Status's message and the additional message are joined
+//   together when the result status is built.
+// - By default, the messages will be joined as if by `util::Annotate`, which
+//   includes a convenience separator between the original message and the
+//   additional one.  This behavior can be changed with the `SetAppend()` and
+//   `SetPrepend()` methods of the builder.
+// - By default, the result status is not logged.  The `Log` and
+//   `EmitStackTrace` methods will cause the builder to log the result status
+//   when it is built.
+// - All side effects (like logging or constructing a stack trace) happen when
+//   the builder is converted to a status.
+class ABSL_MUST_USE_RESULT StatusBuilder {
+ public:
+  explicit StatusBuilder();
+  ~StatusBuilder();
+
+  // Creates a `StatusBuilder` based on an original status.  If logging is
+  // enabled, it will use `location` as the location from which the log message
+  // occurs.  A typical user will not specify `location`, allowing it to default
+  // to the current location.
+  explicit StatusBuilder(
+      const absl::Status& original_status,
+      absl::SourceLocation location = absl::SourceLocation::current());
+  explicit StatusBuilder(
+      absl::Status&& original_status,
+      absl::SourceLocation location = absl::SourceLocation::current());
+
+  // Creates a `StatusBuilder` from a status code.  If logging is enabled, it
+  // will use `location` as the location from which the log message occurs.  A
+  // typical user will not specify `location`, allowing it to default to the
+  // current location.
+  explicit StatusBuilder(
+      absl::StatusCode code,
+      absl::SourceLocation location = absl::SourceLocation::current());
+
+  StatusBuilder(const StatusBuilder& sb);
+  StatusBuilder& operator=(const StatusBuilder& sb);
+  StatusBuilder(StatusBuilder&&) = default;
+  StatusBuilder& operator=(StatusBuilder&&) = default;
+
+  // Mutates the builder so that the final additional message is prepended to
+  // the original error message in the status.  A convenience separator is not
+  // placed between the messages.
+  //
+  // NOTE: Multiple calls to `SetPrepend` and `SetAppend` just adjust the
+  // behavior of the final join of the original status with the extra message.
+  //
+  // Returns `*this` to allow method chaining.
+  StatusBuilder& SetPrepend() &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& SetPrepend() &&;
+
+  // Mutates the builder so that the final additional message is appended to the
+  // original error message in the status.  A convenience separator is not
+  // placed between the messages.
+  //
+  // NOTE: Multiple calls to `SetPrepend` and `SetAppend` just adjust the
+  // behavior of the final join of the original status with the extra message.
+  //
+  // Returns `*this` to allow method chaining.
+  StatusBuilder& SetAppend() &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& SetAppend() &&;
+
+  // Mutates the builder to disable any logging that was set using any of the
+  // logging functions below.  Returns `*this` to allow method chaining.
+  StatusBuilder& SetNoLogging() &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& SetNoLogging() &&;
+
+  // Mutates the builder so that the result status will be logged (without a
+  // stack trace) when this builder is converted to a Status.  This overrides
+  // the logging settings from earlier calls to any of the logging mutator
+  // functions.  Returns `*this` to allow method chaining.
+  StatusBuilder& Log(absl::LogSeverity level) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& Log(absl::LogSeverity level) &&;
+
+  StatusBuilder& LogError() & { return Log(absl::LogSeverity::kError); }
+  ABSL_MUST_USE_RESULT StatusBuilder&& LogError() && {
+    return std::move(LogError());
+  }
+  StatusBuilder& LogWarning() & { return Log(absl::LogSeverity::kWarning); }
+  ABSL_MUST_USE_RESULT StatusBuilder&& LogWarning() && {
+    return std::move(LogWarning());
+  }
+  StatusBuilder& LogInfo() & { return Log(absl::LogSeverity::kInfo); }
+  ABSL_MUST_USE_RESULT StatusBuilder&& LogInfo() && {
+    return std::move(LogInfo());
+  }
+
+  // Mutates the builder so that the result status will be logged every N
+  // invocations (without a stack trace) when this builder is converted to a
+  // Status.  This overrides the logging settings from earlier calls to any of
+  // the logging mutator functions.  Returns `*this` to allow method chaining.
+  StatusBuilder& LogEveryN(absl::LogSeverity level, int n) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& LogEveryN(absl::LogSeverity level,
+                                                 int n) &&;
+
+  // Mutates the builder so that the result status will be logged once per
+  // period (without a stack trace) when this builder is converted to a Status.
+  // This overrides the logging settings from earlier calls to any of the
+  // logging mutator functions.  Returns `*this` to allow method chaining.
+  // If period is absl::ZeroDuration() or less, then this is equivalent to
+  // calling the Log() method.
+  StatusBuilder& LogEvery(absl::LogSeverity level, absl::Duration period) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& LogEvery(absl::LogSeverity level,
+                                                absl::Duration period) &&;
+
+  // Mutates the builder so that the result status will be VLOGged (without a
+  // stack trace) when this builder is converted to a Status.  `verbose_level`
+  // indicates the verbosity level that would be passed to VLOG().  This
+  // overrides the logging settings from earlier calls to any of the logging
+  // mutator functions.  Returns `*this` to allow method chaining.
+  StatusBuilder& VLog(int verbose_level) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& VLog(int verbose_level) &&;
+
+  // Mutates the builder so that a stack trace will be logged if the status is
+  // logged. One of the logging setters above should be called as well. If
+  // logging is not yet enabled this behaves as if LogInfo().EmitStackTrace()
+  // was called. Returns `*this` to allow method chaining.
+  StatusBuilder& EmitStackTrace() &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& EmitStackTrace() &&;
+
+  // Mutates the builder so that the result status will also be logged to the
+  // provided `sink` when this builder is converted to a status. Overwrites any
+  // sink set prior. The provided `sink` must point to a valid object by the
+  // time this builder is converted to a status. Has no effect if this builder
+  // is not configured to log by calling any of the LogXXX methods. Returns
+  // `*this` to allow method chaining.
+  StatusBuilder& AlsoOutputToSink(absl::LogSink* sink) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& AlsoOutputToSink(absl::LogSink* sink) &&;
+
+  // Mutates the builder so that the result status will only be logged to the
+  // provided `sink` when this builder is converted to a status. Overwrites any
+  // sink set prior. The provided `sink` must point to a valid object by the
+  // time this builder is converted to a status. Has no effect if this builder
+  // is not configured to log by calling any of the LogXXX methods. Returns
+  // `*this` to allow method chaining.
+  StatusBuilder& OnlyOutputToSink(absl::LogSink* sink) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& OnlyOutputToSink(absl::LogSink* sink) &&;
+
+  // Appends to the extra message that will be added to the original status.  By
+  // default, the extra message is added to the original message as if by
+  // `util::Annotate`, which includes a convenience separator between the
+  // original message and the enriched one.
+  template <typename T>
+  StatusBuilder& operator<<(const T& value) &;
+
+  template <typename T>
+  ABSL_MUST_USE_RESULT StatusBuilder&& operator<<(const T& value) &&;
+
+  // Adds a payload for the status that will be returned by this StatusBuilder.
+  // Note that this is equivalent to `Status::SetPayload`, to attach protos to
+  // the MessageSet payload, use `util::AttachPayload`. Returns '*this' to allow
+  // method chaining.
+  StatusBuilder& SetPayload(absl::string_view type_url, absl::Cord payload) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& SetPayload(absl::string_view type_url,
+                                                  absl::Cord payload) && {
+    return std::move(SetPayload(type_url, std::move(payload)));
+  }
+
+  std::optional<absl::Cord> GetPayload(absl::string_view type_url) const;
+
+  // INTERNAL API. NOT FOR PUBLIC USE.
+  template <typename MessageSetExtension, typename ExtensionIdentifier>
+  auto AttachPayload(const MessageSetExtension& obj,
+                     const ExtensionIdentifier& id) &  //
+      -> std::enable_if_t<
+          std::is_void_v<decltype(AbslInternalAttachPayload(*this, obj, id))>,
+          StatusBuilder&> {
+    AbslInternalAttachPayload(*this, obj, id);
+    return *this;
+  }
+
+  // As above, but &&-qualified.
+  //
+  // Uses decltype() to propagate template constraints (SFINAE).
+  template <typename MessageSetExtension, typename ExtensionIdentifier>
+  ABSL_MUST_USE_RESULT auto AttachPayload(const MessageSetExtension& obj,
+                                          const ExtensionIdentifier& id) &&  //
+      -> decltype(std::move(AttachPayload(obj, id))) {
+    return std::move(AttachPayload(obj, id));
+  }
+
+  // Like `AttachPayload() &`, but with the default extension ID.
+  //
+  // INTERNAL API. NOT FOR PUBLIC USE.
+  template <typename MessageSetExtension>
+  auto AttachPayload(const MessageSetExtension& obj) &  //
+      -> std::enable_if_t<
+          std::is_void_v<decltype(AbslInternalAttachPayload(*this, obj))>,
+          StatusBuilder&> {
+    AbslInternalAttachPayload(*this, obj);
+    return *this;
+  }
+
+  // As above, but &&-qualified.
+  //
+  // Uses decltype() to propagate template constraints (SFINAE).
+  template <typename MessageSetExtension>
+  ABSL_MUST_USE_RESULT auto AttachPayload(const MessageSetExtension& obj) &&  //
+      -> decltype(std::move(AttachPayload(obj))) {
+    return std::move(AttachPayload(obj));
+  }
+
+  // HasPayload()
+  //
+  // Indicates whether the Status object that will be returned by the
+  // StatusBuilder contains any payloads with a type extending proto2's
+  // `MessageSet`, returning `true` if so. Having a payload does not guarantee
+  // the presence of a payload with a specific type. Note that returning `false`
+  // does not necessarily indicate the absence of a payload, but only the
+  // absence on one which extends `MessageSet`.
+  bool HasPayload() const;
+
+  // INTERNAL API. NOT FOR PUBLIC USE.
+  template <typename Enum>
+  auto SetErrorCode(Enum code) &  //
+      -> std::enable_if_t<
+          std::is_void_v<decltype(AbslInternalSetErrorCode(*this, code))>,
+          StatusBuilder&> {
+    AbslInternalSetErrorCode(*this, code);
+    return *this;
+  }
+
+  // As above, but &&-qualified.
+  //
+  // Uses decltype() to propagate template constraints (SFINAE).
+  template <typename Enum>
+  ABSL_MUST_USE_RESULT auto SetErrorCode(Enum code) &&  //
+      -> decltype(std::move(SetErrorCode(code))) {
+    return std::move(SetErrorCode(code));
+  }
+
+  // Sets the status code for the status that will be returned by this
+  // StatusBuilder. Returns `*this` to allow method chaining.
+  StatusBuilder& SetCode(absl::StatusCode code) &;
+  ABSL_MUST_USE_RESULT StatusBuilder&& SetCode(absl::StatusCode code) && {
+    return std::move(SetCode(code));
+  }
+
+  ///////////////////////////////// Adaptors /////////////////////////////////
+  //
+  // A StatusBuilder `adaptor` is a functor which can be included in a builder
+  // method chain. There are two common variants:
+  //
+  // 1. `Pure policy` adaptors modify the StatusBuilder and return the modified
+  //    object, which can then be chained with further adaptors or mutations.
+  //
+  // 2. `Terminal` adaptors consume the builder's Status and return some
+  //    other type of object. Alternatively, the consumed Status may be used
+  //    for side effects, e.g. by passing it to a side channel. A terminal
+  //    adaptor cannot be chained.
+  //
+  // Careful: The conversion of StatusBuilder to Status has side effects!
+  // Adaptors must ensure that this conversion happens at most once in the
+  // builder chain. The easiest way to do this is to determine the adaptor type
+  // and follow the corresponding guidelines:
+  //
+  // Pure policy adaptors should:
+  // (a) Take a StatusBuilder as input parameter.
+  // (b) NEVER convert the StatusBuilder to Status:
+  //     - Never assign the builder to a Status variable.
+  //     - Never pass the builder to a function whose parameter type is Status,
+  //       including by reference (e.g. const Status&).
+  //     - Never pass the builder to any function which might convert the
+  //       builder to Status (i.e. this restriction is viral).
+  // (c) Return a StatusBuilder (usually the input parameter).
+  //
+  // Terminal adaptors should:
+  // (a) Take a Status as input parameter (not a StatusBuilder!).
+  // (b) Return a type matching the enclosing function. (This can be `void`.)
+  //
+  // Adaptors do not necessarily fit into one of these categories. However, any
+  // which satisfies the conversion rule can always be decomposed into a pure
+  // adaptor chained into a terminal adaptor. (This is recommended.)
+  //
+  // Examples
+  //
+  // Pure adaptors allow teams to configure team-specific error handling
+  // policies.  For example:
+  //
+  //   StatusBuilder TeamPolicy(StatusBuilder builder) {
+  //     builder.SetPayload(...);
+  //     return std::move(builder).Log(absl::LogSeverity::kWarning);
+  //   }
+  //
+  //   ABSL_RETURN_IF_ERROR(foo()).With(TeamPolicy);
+  //
+  // Because pure policy adaptors return the modified StatusBuilder, they
+  // can be chained with further adaptors, e.g.:
+  //
+  //   ABSL_RETURN_IF_ERROR(foo()).With(TeamPolicy).With(OtherTeamPolicy);
+  //
+  // Terminal adaptors are often used for type conversion. This allows
+  // ABSL_RETURN_IF_ERROR to be used in functions which do not return Status.
+  // For example, a function might want to return some default value on error:
+  //
+  //   int GetSysCounter() {
+  //     int value;
+  //     ABSL_RETURN_IF_ERROR(ReadCounterFile(filename, &value))
+  //         .LogInfo()
+  //         .With([](const absl::Status& unused) { return 0; });
+  //     return value;
+  //   }
+  //
+  // For the simple case of returning a constant (e.g. zero, false, nullptr) on
+  // error, consider `status_macros::Return` or `status_macros::ReturnVoid`:
+  //
+  //   #include "util/task/contrib/status_macros/return.h"
+  //
+  //   bool DoMyThing() {
+  //     ABSL_RETURN_IF_ERROR(foo()).LogWarning().With(status_macros::Return(false));
+  //     ...
+  //   }
+  //
+  // A terminal adaptor may instead (or additionally) be used to create side
+  // effects that are not supported natively by `StatusBuilder`, such as
+  // returning the Status through a side channel. For example,
+  // `util::TaskReturn` returns the Status through the `util::Task` that it was
+  // initialized with. This adaptor then returns `void`, to match the typical
+  // return type of functions that maintain state through `util::Task`:
+  //
+  //   class TaskReturn {
+  //    public:
+  //     explicit TaskReturn(Task* t) : task_(t) {}
+  //     void operator()(const Status& status) const { task_->Return(status); }
+  //     // ...
+  //   };
+  //
+  //   void Read(absl::string_view name, util::Task* task) {
+  //     int64 id;
+  //     ABSL_RETURN_IF_ERROR(GetIdForName(name, &id)).With(TaskReturn(task));
+  //     ABSL_RETURN_IF_ERROR(ReadForId(id)).With(TaskReturn(task));
+  //     task->Return();
+  //   }
+
+  // Calls `adaptor` on this status builder to apply policies, type conversions,
+  // and/or side effects on the StatusBuilder. Returns the value returned by
+  // `adaptor`, which may be any type including `void`. See comments above.
+  //
+  // Style guide exception for Ref qualified methods and rvalue refs
+  // (cl/128258530).  This allows us to avoid a copy in the common case.
+  //
+  // Note: All With() overrides are equivalent, and return Adaptor(this). They
+  // are part of an ongoing LSC investigation.
+  template <typename Adaptor>
+  auto With(Adaptor&& adaptor) & -> status_internal::PurePolicy<
+      Adaptor, StatusBuilder&> {
+    return std::forward<Adaptor>(adaptor)(*this);
+  }
+  template <typename Adaptor>
+  ABSL_MUST_USE_RESULT auto With(
+      Adaptor&&
+          adaptor) && -> status_internal::PurePolicy<Adaptor, StatusBuilder&&> {
+    return std::forward<Adaptor>(adaptor)(std::move(*this));
+  }
+
+  template <typename Adaptor>
+  auto With(Adaptor&& adaptor) & -> status_internal::SideEffect<
+      Adaptor, StatusBuilder&> {
+    return std::forward<Adaptor>(adaptor)(*this);
+  }
+  template <typename Adaptor>
+  ABSL_MUST_USE_RESULT auto With(
+      Adaptor&&
+          adaptor) && -> status_internal::SideEffect<Adaptor, StatusBuilder&&> {
+    return std::forward<Adaptor>(adaptor)(std::move(*this));
+  }
+
+  template <typename Adaptor>
+  auto With(Adaptor&& adaptor) & -> status_internal::Conversion<
+      Adaptor, StatusBuilder&> {
+    return std::forward<Adaptor>(adaptor)(*this);
+  }
+  template <typename Adaptor>
+  ABSL_MUST_USE_RESULT auto With(
+      Adaptor&&
+          adaptor) && -> status_internal::Conversion<Adaptor, StatusBuilder&&> {
+    return std::forward<Adaptor>(adaptor)(std::move(*this));
+  }
+
+  // Returns true if the Status created by this builder will be ok().
+  ABSL_MUST_USE_RESULT bool ok() const;
+
+  // Returns the (canonical) error code for the Status created by this builder.
+  absl::StatusCode code() const;
+
+  // Implicit conversion to Status.
+  //
+  // Careful: this operator has side effects, so it should be called at
+  // most once. In particular, do NOT use this conversion operator to inspect
+  // the status from an adapter object passed into With().
+  //
+  // Style guide exception for using Ref qualified methods and for implicit
+  // conversions (cl/124566728).  This override allows us to implement
+  // ABSL_RETURN_IF_ERROR with 2 move operations in the common case.
+  operator absl::Status() const&;  // NOLINT: Builder converts implicitly.
+  operator absl::Status() &&;      // NOLINT: Builder converts implicitly.
+
+  // Returns the source location used to create this builder. This differs from
+  // `GetPreviousSourceLocations()` as this location is the single location for
+  // the creation of this builder.
+  ABSL_MUST_USE_RESULT absl::SourceLocation source_location() const;
+
+  // Returns the source locations previously recorded in the status. This will
+  // not include the source location of the `StatusBuilder` itself (which is
+  // available via `source_location()`). When the builder is converted to a
+  // Status, the builder's location will be appended to this list of previous
+  // locations. For `StatusBuilder`s created without an original status (e.g.,
+  // from a status code), this will be empty.
+  decltype(auto) GetPreviousSourceLocations() const {
+    if (rep_ == nullptr) {
+      return absl::OkStatus().GetSourceLocations();
+    }
+    return rep_->status.GetSourceLocations();
+  }
+
+  // Returns a string based on the `mode`. This produces the same string as
+  // would converting to a Status and calling operator<<, but it does so without
+  // side effects (e.g., logging). Therefore, it is safe to use from within an
+  // adapter object passed into With().
+  std::string ToString() const;
+
+ private:
+  friend class status_internal::StatusBuilderPrivateAccessor;
+
+  // Returns true if the compiler can determine that the instance is empty. That
+  // is, `rep_ == nullptr`.
+  // A `false` return does not necessarily indicate that it has a rep. It just
+  // can't prove it doesn't.
+  ABSL_ATTRIBUTE_ALWAYS_INLINE bool IsKnownToBeEmpty() const {
+#if ABSL_HAVE_BUILTIN(__builtin_constant_p)
+    // __builtin_constant_p does not like it when it has non trivial expressions
+    // in it, and `rep_==nullptr` is a user-defined operator.
+    // Do it out of the builtin and pass the bool instead.
+    bool is_empty = rep_ == nullptr;
+    return __builtin_constant_p(is_empty) && is_empty;
+#else
+    return false;
+#endif
+  }
+
+  // Tells the compiler that it can assume that `rep_` is null.
+  // This is verified in non-opt mode.
+  void AssumeEmpty() const {
+    if (rep_ != nullptr) ABSL_UNREACHABLE();
+  }
+
+  static std::string CurrentStackTrace();
+
+  struct Rep;
+  // Destroy the `Rep` object. It is just calling the destructor of the
+  // `unique_ptr`, but out of line.
+  static void Destroy(std::unique_ptr<Rep>);
+
+  // Creates a Status from this builder and logs it if the builder has been
+  // configured to log itself.
+  // NOTE: This function is `static` to prevent escaping the `this` pointer. We
+  //       transfer the `Rep` to delegate the destruction.
+  static absl::Status CreateStatusAndConditionallyLog(absl::SourceLocation loc,
+                                                      std::unique_ptr<Rep> rep);
+
+  // Infrequently set builder options, instantiated lazily. This reduces
+  // average construction/destruction time (e.g. the `stream` is fairly
+  // expensive). Stacks can also be blown if StatusBuilder grows too large.
+  // This is primarily an issue for debug builds, which do not necessarily
+  // re-use stack space within a function across the sub-scopes used by
+  // status macros.
+  struct Rep {
+    explicit Rep(const absl::Status& s);
+    explicit Rep(absl::Status&& s);
+    Rep(const Rep& r);
+    ~Rep();
+    void InitStream();
+
+    // The status that the result will be based on.  Can be modified by
+    // SetPayload().
+    absl::Status status;
+
+    enum class LoggingMode {
+      kDisabled,
+      kLog,
+      kVLog,
+      kLogEveryN,
+      kLogEveryPeriod
+    };
+    LoggingMode logging_mode = LoggingMode::kDisabled;
+
+    // The severity level at which the Status should be logged. Note that
+    // `logging_mode == LoggingMode::kVLog` always logs at severity INFO.
+    absl::LogSeverity log_severity;
+
+    // The level at which the Status should be VLOGged.
+    // Only used when `logging_mode == LoggingMode::kVLog`.
+    int verbose_level;
+
+    // Only log every N invocations.
+    // Only used when `logging_mode == LoggingMode::kLogEveryN`.
+    int n;
+
+    // Only log once per period.
+    // Only used when `logging_mode == LoggingMode::kLogEveryPeriod`.
+    absl::Duration period;
+
+    // Gathers additional messages added with `<<` for use in the final status.
+    std::string stream_message;
+    std::optional<status_internal::Stream> stream;
+
+    // If not nullptr, specifies the log sink where log output should be
+    // sent to.  Only used when `logging_mode != LoggingMode::kDisabled`.
+    absl::LogSink* sink = nullptr;
+
+    // Specifies how to join the message in `status` and `stream`.
+    MessageJoinStyle message_join_style = MessageJoinStyle::kAnnotate;
+
+    // Whether to log stack trace.  Only used when `logging_mode !=
+    // LoggingMode::kDisabled`.
+    bool should_log_stack_trace = false;
+
+    // When this is true, will send both to `sink` and will log. When this is
+    // false, will only send to `sink`.
+    bool also_send_to_log = true;
+  };
+
+  static Rep* InitRep(const absl::Status& s) {
+    if (s.ok()) {
+      return nullptr;
+    } else {
+      return new Rep(s);
+    }
+  }
+
+  static Rep* InitRep(absl::Status&& s) {
+    if (s.ok()) {
+      return nullptr;
+    } else {
+      Rep* rep = InitRepImpl(std::move(s));
+      ABSL_ASSUME(rep != nullptr);
+      return rep;
+    }
+  }
+
+  // Out of line function that constructs the Rep.
+  // Note that `s` is by value because of the TRIVIAL_ABI.
+  static Rep* InitRepImpl(absl::Status s);
+
+  // The location to record if this status is logged.
+  absl::SourceLocation loc_;
+
+  // nullptr if the result status will be OK.  Extra fields moved to the heap to
+  // minimize stack space.
+  std::unique_ptr<Rep> rep_;
+
+  // For testing Rep's implememntation.
+  friend class StatusBuilderTest;
+};
+
+// Implicitly converts `builder` to `Status` and write it to `os`.
+std::ostream& operator<<(std::ostream& os, const StatusBuilder& builder);
+std::ostream& operator<<(std::ostream& os, StatusBuilder&& builder);
+
+// StatusBuilder policy to append an extra message to the original status.
+//
+// This is most useful with adaptors such as util::TaskReturn that otherwise
+// would prevent use of operator<<.  For example:
+//
+//   ABSL_RETURN_IF_ERROR(foo(val))
+//       .With(util::ExtraMessage("when calling foo()"))
+//       .With(util::TaskReturn(task));
+//
+// or
+//
+//   ABSL_RETURN_IF_ERROR(foo(val))
+//       .With(util::ExtraMessage() << "val: " << val)
+//       .With(util::TaskReturn(task));
+//
+// Note in the above example, the ABSL_RETURN_IF_ERROR macro ensures the
+// ExtraMessage expression is evaluated only in the error case, so efficiency of
+// constructing the message is not a concern in the success case.
+class ExtraMessage {
+ public:
+  ExtraMessage() : ExtraMessage(std::string()) {}
+  explicit ExtraMessage(std::string msg)
+      : msg_(std::move(msg)), stream_(msg_) {}
+
+  ExtraMessage(
+      ExtraMessage&& other) noexcept  // strings::OStringStream is stateless
+                                      // so we can simply move over the message.
+      : ExtraMessage(std::move(other.msg_)) {}
+
+  // Appends to the extra message that will be added to the original status.  By
+  // default, the extra message is added to the original message as if by
+  // `util::Annotate`, which includes a convenience separator between the
+  // original message and the enriched one.
+  template <typename T>
+  ExtraMessage& operator<<(const T& value) & {
+    stream_ << value;
+    return *this;
+  }
+
+  // As above, preserving the rvalue-ness of the ExtraMessage object.
+  template <typename T>
+  ExtraMessage&& operator<<(const T& value) && {
+    *this << value;
+    return std::move(*this);
+  }
+
+  // Appends to the extra message that will be added to the original status.  By
+  // default, the extra message is added to the original message as if by
+  // `util::Annotate`, which includes a convenience separator between the
+  // original message and the enriched one.
+  StatusBuilder operator()(StatusBuilder builder) const {
+    builder << msg_;
+    return builder;
+  }
+
+ private:
+  std::string msg_;
+  status_internal::Stream stream_;
+};
+
+// Implementation details follow; clients should ignore.
+
+inline StatusBuilder::StatusBuilder(absl::StatusCode code,
+                                    absl::SourceLocation location)
+    : loc_(location), rep_(InitRep(absl::Status(code, ""))) {}
+
+inline StatusBuilder::StatusBuilder(const StatusBuilder& sb) : loc_(sb.loc_) {
+  if (sb.rep_ != nullptr) {
+    rep_ = std::make_unique<Rep>(*sb.rep_);
+  }
+}
+
+inline StatusBuilder::StatusBuilder(absl::Status&& original_status,
+                                    absl::SourceLocation location)
+    : loc_(location), rep_(InitRep(std::move(original_status))) {}
+
+inline StatusBuilder::~StatusBuilder() {
+  if (IsKnownToBeEmpty()) {
+    // Nothing to do.
+    return;
+  }
+  // We will run the destructor logic, so move it out of line.
+  // The destructor of the unique_ptr runs ~Rep() and then ::operator delete.
+  // We don't want that bloat on the caller.
+  Destroy(std::move(rep_));
+  // Tell the compiler that `rep_` was not filled again even if `this` escaped.
+  AssumeEmpty();
+}
+
+inline StatusBuilder& StatusBuilder::operator=(const StatusBuilder& sb) {
+  loc_ = sb.loc_;
+  if (sb.rep_ != nullptr) {
+    rep_ = std::make_unique<Rep>(*sb.rep_);
+  } else {
+    rep_ = nullptr;
+  }
+  return *this;
+}
+
+inline StatusBuilder& StatusBuilder::SetPrepend() & {
+  if (rep_ == nullptr) return *this;
+  rep_->message_join_style = MessageJoinStyle::kPrepend;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::SetPrepend() && {
+  return std::move(SetPrepend());
+}
+
+inline StatusBuilder& StatusBuilder::SetAppend() & {
+  if (rep_ == nullptr) return *this;
+  rep_->message_join_style = MessageJoinStyle::kAppend;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::SetAppend() && {
+  return std::move(SetAppend());
+}
+
+inline StatusBuilder& StatusBuilder::SetNoLogging() & {
+  if (rep_ != nullptr) {
+    rep_->logging_mode = Rep::LoggingMode::kDisabled;
+    rep_->should_log_stack_trace = false;
+  }
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::SetNoLogging() && {
+  return std::move(SetNoLogging());
+}
+
+inline StatusBuilder& StatusBuilder::Log(absl::LogSeverity level) & {
+  if (rep_ == nullptr) return *this;
+  rep_->logging_mode = Rep::LoggingMode::kLog;
+  rep_->log_severity = level;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::Log(absl::LogSeverity level) && {
+  return std::move(Log(level));
+}
+
+inline StatusBuilder& StatusBuilder::LogEveryN(absl::LogSeverity level,
+                                               int n) & {
+  if (rep_ == nullptr) return *this;
+  if (n < 1) return Log(level);
+  rep_->logging_mode = Rep::LoggingMode::kLogEveryN;
+  rep_->log_severity = level;
+  rep_->n = n;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::LogEveryN(absl::LogSeverity level,
+                                                int n) && {
+  return std::move(LogEveryN(level, n));
+}
+
+inline StatusBuilder& StatusBuilder::LogEvery(absl::LogSeverity level,
+                                              absl::Duration period) & {
+  if (rep_ == nullptr) return *this;
+  if (period <= absl::ZeroDuration()) return Log(level);
+  rep_->logging_mode = Rep::LoggingMode::kLogEveryPeriod;
+  rep_->log_severity = level;
+  rep_->period = period;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::LogEvery(absl::LogSeverity level,
+                                               absl::Duration period) && {
+  return std::move(LogEvery(level, period));
+}
+
+inline StatusBuilder& StatusBuilder::VLog(int verbose_level) & {
+  if (rep_ == nullptr) return *this;
+  rep_->logging_mode = Rep::LoggingMode::kVLog;
+  rep_->verbose_level = verbose_level;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::VLog(int verbose_level) && {
+  return std::move(VLog(verbose_level));
+}
+
+inline StatusBuilder& StatusBuilder::EmitStackTrace() & {
+  if (rep_ == nullptr) return *this;
+  if (rep_->logging_mode == Rep::LoggingMode::kDisabled) {
+    // Default to INFO logging, otherwise nothing would be emitted.
+    rep_->logging_mode = Rep::LoggingMode::kLog;
+    rep_->log_severity = absl::LogSeverity::kInfo;
+  }
+  rep_->should_log_stack_trace = true;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::EmitStackTrace() && {
+  return std::move(EmitStackTrace());
+}
+
+inline StatusBuilder& StatusBuilder::AlsoOutputToSink(absl::LogSink* sink) & {
+  if (rep_ == nullptr) return *this;
+  rep_->sink = sink;
+  rep_->also_send_to_log = true;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::AlsoOutputToSink(absl::LogSink* sink) && {
+  return std::move(AlsoOutputToSink(sink));
+}
+inline StatusBuilder& StatusBuilder::OnlyOutputToSink(absl::LogSink* sink) & {
+  if (rep_ == nullptr) return *this;
+  rep_->sink = sink;
+  rep_->also_send_to_log = false;
+  return *this;
+}
+inline StatusBuilder&& StatusBuilder::OnlyOutputToSink(absl::LogSink* sink) && {
+  return std::move(OnlyOutputToSink(sink));
+}
+
+template <typename T>
+StatusBuilder& StatusBuilder::operator<<(const T& value) & {
+  if (rep_ == nullptr) return *this;
+  if (!rep_->stream.has_value()) {
+    rep_->InitStream();
+  }
+  *rep_->stream << value;
+  return *this;
+}
+
+template <typename T>
+StatusBuilder&& StatusBuilder::operator<<(const T& value) && {
+  return std::move(operator<<(value));
+}
+
+inline StatusBuilder& StatusBuilder::SetPayload(absl::string_view type_url,
+                                                absl::Cord payload) & {
+  if (rep_ != nullptr) {
+    rep_->status.SetPayload(type_url, std::move(payload));
+  }
+  return *this;
+}
+
+inline std::optional<absl::Cord> StatusBuilder::GetPayload(
+    absl::string_view type_url) const {
+  return rep_ == nullptr ? std::nullopt : rep_->status.GetPayload(type_url);
+}
+
+inline bool StatusBuilder::ok() const {
+  return rep_ == nullptr ? true : rep_->status.ok();
+}
+
+inline absl::StatusCode StatusBuilder::code() const {
+  return rep_ == nullptr ? absl::StatusCode::kOk : rep_->status.code();
+}
+
+inline StatusBuilder::operator absl::Status() && {
+  // Tell the compiler that the `ok()` path will return an `Ok` status, but do
+  // it only if the compiler can determine it at compile time.
+  // When it can't, we delegate this check into the out of line function.
+  if (IsKnownToBeEmpty()) {
+    return absl::OkStatus();
+  }
+  absl::Status result = CreateStatusAndConditionallyLog(loc_, std::move(rep_));
+  // Tell the compiler that `rep_` was not filled again even if `this` escaped.
+  AssumeEmpty();
+  return result;
+}
+
+inline absl::SourceLocation StatusBuilder::source_location() const {
+  return loc_;
+}
+
+// HasPayload()
+//
+// Indicates whether the Status object that will be returned by the
+// StatusBuilder contains any payloads with a type extending proto2's
+// `MessageSet`, returning `true` if so. Having a payload does not guarantee the
+// presence of a payload with a specific type. Note that returning `false` does
+// not necessarily indicate the absence of a payload, but only the absence on
+// one which extends `MessageSet`.
+inline bool HasPayload(const StatusBuilder& builder) {
+  return builder.HasPayload();
+}
+
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_STATUS_STATUS_BUILDER_H_
diff --git a/absl/status/status_builder_test.cc b/absl/status/status_builder_test.cc
new file mode 100644
index 0000000..28fd6b9
--- /dev/null
+++ b/absl/status/status_builder_test.cc
@@ -0,0 +1,380 @@
+// Copyright 2026 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/status/status_builder.h"
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+#include "absl/log/log.h"
+#include "absl/log/log_entry.h"
+#include "absl/log/log_sink.h"
+#include "absl/status/status.h"
+#include "absl/status/status_matchers.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/source_location.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace {
+
+using ::absl_testing::StatusIs;
+using ::testing::AllOf;
+using ::testing::AnyOf;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::Pointee;
+using ::testing::Property;
+
+// Converts a StatusBuilder to a Status.
+absl::Status ToStatus(const StatusBuilder& s) { return s; }
+
+// Converts a StatusBuilder to a StatusOr<T>.
+template <typename T>
+absl::StatusOr<T> ToStatusOr(const StatusBuilder& s) {
+  return s;
+}
+
+void CheckSourceLocation(
+    const absl::Status& status, std::vector<int> lines = {},
+    absl::SourceLocation loc = absl::SourceLocation::current()) {
+  ASSERT_EQ(status.GetSourceLocations().size(), lines.size())
+      << "Size check failed at " << loc.line();
+  for (size_t i = 0; i < lines.size(); ++i) {
+    EXPECT_EQ(absl::string_view(status.GetSourceLocations()[i].file_name()),
+              absl::string_view(loc.file_name()))
+        << "File name check failed at " << loc.line();
+    EXPECT_EQ(status.GetSourceLocations()[i].line(), lines[i])
+        << "Line check failed at " << loc.line();
+  }
+}
+
+class StatusBuilderTest : public ::testing::Test {};
+
+TEST_F(StatusBuilderTest, Size) {
+  EXPECT_LE(sizeof(StatusBuilder), 40)
+      << "Relax this test with caution and thorough testing. If StatusBuilder "
+         "is too large it can potentially blow stacks, especially in debug "
+         "builds. See the comments for StatusBuilder::Rep.";
+}
+
+TEST_F(StatusBuilderTest, ExplicitSourceLocation) {
+  const absl::SourceLocation kLocation = absl::SourceLocation::current();
+
+  {
+    const StatusBuilder builder(absl::OkStatus(), kLocation);
+    EXPECT_THAT(builder.source_location().file_name(),
+                Eq(kLocation.file_name()));
+    EXPECT_THAT(builder.source_location().line(), Eq(kLocation.line()));
+  }
+}
+
+TEST_F(StatusBuilderTest, ImplicitSourceLocation) {
+  const StatusBuilder builder(absl::OkStatus());
+  auto loc = absl::SourceLocation::current();
+  EXPECT_THAT(builder.source_location().file_name(),
+              AnyOf(Eq(absl::string_view(loc.file_name())),
+                    Eq(absl::string_view("<source_location>"))));
+  EXPECT_THAT(builder.source_location().line(),
+              AnyOf(Eq(1), Eq(loc.line() - 1)));
+}
+
+testing::Matcher<absl::SourceLocation> SourceLocationIs(
+    absl::SourceLocation loc) {
+  return AnyOf(
+      AllOf(Property(&absl::SourceLocation::file_name, Eq(loc.file_name())),
+            Property(&absl::SourceLocation::line, Eq(loc.line()))),
+      // Fallback for platforms that don't support source locations.
+      AllOf(Property(&absl::SourceLocation::file_name, Eq("<source_location>")),
+            Property(&absl::SourceLocation::line, Eq(1))));
+}
+
+TEST_F(StatusBuilderTest, GetPreviousSourceLocations) {
+  const absl::SourceLocation loc0 = absl::SourceLocation::current();
+  absl::Status status = absl::InvalidArgumentError("hi", loc0);
+  const absl::SourceLocation loc1 = absl::SourceLocation::current();
+  status.AddSourceLocation(loc1);
+  const absl::SourceLocation loc2 = absl::SourceLocation::current();
+  status.AddSourceLocation(loc2);
+
+  // The builder's location is not included.
+  const StatusBuilder builder(status);
+  EXPECT_THAT(builder.GetPreviousSourceLocations(),
+              ElementsAre(SourceLocationIs(loc0), SourceLocationIs(loc1),
+                          SourceLocationIs(loc2)));
+}
+
+TEST_F(StatusBuilderTest, EmptyGetPreviousSourceLocationsForNewFromStatusCode) {
+  const StatusBuilder builder(absl::StatusCode::kInvalidArgument);
+  EXPECT_THAT(builder.GetPreviousSourceLocations(), IsEmpty());
+}
+
+TEST_F(StatusBuilderTest, StatusCode) {
+  // OK
+  {
+    const StatusBuilder builder(absl::StatusCode::kOk);
+    EXPECT_TRUE(builder.ok());
+    EXPECT_THAT(builder.code(), Eq(absl::StatusCode::kOk));
+  }
+  // Non-OK code
+  {
+    const StatusBuilder builder(absl::StatusCode::kInvalidArgument);
+    EXPECT_FALSE(builder.ok());
+    EXPECT_THAT(builder.code(), Eq(absl::StatusCode::kInvalidArgument));
+  }
+}
+
+TEST_F(StatusBuilderTest, OkIgnoresStuff) {
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::OkStatus(), absl::SourceLocation())
+                       << "booyah"),
+              Eq(absl::OkStatus()));
+}
+
+TEST_F(StatusBuilderTest, Streaming) {
+  EXPECT_THAT(
+      ToStatus(StatusBuilder(absl::CancelledError(), absl::SourceLocation())
+               << "booyah"),
+      Eq(absl::CancelledError("booyah")));
+  EXPECT_THAT(
+      ToStatus(
+          StatusBuilder(absl::AbortedError("hello"), absl::SourceLocation())
+          << "world"),
+      Eq(absl::AbortedError("hello; world")));
+}
+
+TEST_F(StatusBuilderTest, PrependLvalue) {
+  {
+    StatusBuilder builder(absl::CancelledError(), absl::SourceLocation());
+    EXPECT_THAT(ToStatus(builder.SetPrepend() << "booyah"),
+                Eq(absl::CancelledError("booyah")));
+  }
+  {
+    StatusBuilder builder(absl::AbortedError(" hello"), absl::SourceLocation());
+    EXPECT_THAT(ToStatus(builder.SetPrepend() << "world"),
+                Eq(absl::AbortedError("world hello")));
+  }
+}
+
+TEST_F(StatusBuilderTest, PrependRvalue) {
+  EXPECT_THAT(
+      ToStatus(StatusBuilder(absl::CancelledError(), absl::SourceLocation())
+                   .SetPrepend()
+               << "booyah"),
+      Eq(absl::CancelledError("booyah")));
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError(" hello"),
+                                     absl::SourceLocation())
+                           .SetPrepend()
+                       << "world"),
+              Eq(absl::AbortedError("world hello")));
+}
+
+TEST_F(StatusBuilderTest, AppendLvalue) {
+  {
+    StatusBuilder builder(absl::CancelledError(), absl::SourceLocation());
+    EXPECT_THAT(ToStatus(builder.SetAppend() << "booyah"),
+                Eq(absl::CancelledError("booyah")));
+  }
+  {
+    StatusBuilder builder(absl::AbortedError("hello"), absl::SourceLocation());
+    EXPECT_THAT(ToStatus(builder.SetAppend() << " world"),
+                Eq(absl::AbortedError("hello world")));
+  }
+}
+
+TEST_F(StatusBuilderTest, AppendRvalue) {
+  EXPECT_THAT(
+      ToStatus(StatusBuilder(absl::CancelledError(), absl::SourceLocation())
+                   .SetAppend()
+               << "booyah"),
+      Eq(absl::CancelledError("booyah")));
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .SetAppend()
+                       << " world"),
+              Eq(absl::AbortedError("hello world")));
+}
+
+TEST_F(StatusBuilderTest, WithRvalueRef) {
+  auto policy = [](StatusBuilder sb) { return sb << "policy"; };
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .With(policy)),
+              Eq(absl::AbortedError("hello; policy")));
+}
+
+TEST_F(StatusBuilderTest, WithRef) {
+  auto policy = [](StatusBuilder sb) { return sb << "policy"; };
+  StatusBuilder sb(absl::AbortedError("zomg"), absl::SourceLocation());
+  EXPECT_THAT(ToStatus(sb.With(policy)),
+              Eq(absl::AbortedError("zomg; policy")));
+}
+
+TEST_F(StatusBuilderTest, WithTypeChange) {
+  auto policy = [](StatusBuilder sb) -> std::string {
+    return sb.ok() ? "true" : "false";
+  };
+  EXPECT_EQ(StatusBuilder(absl::CancelledError(), absl::SourceLocation())
+                .With(policy),
+            "false");
+  EXPECT_EQ(
+      StatusBuilder(absl::OkStatus(), absl::SourceLocation()).With(policy),
+      "true");
+}
+
+struct MoveOnlyAdaptor {
+  std::unique_ptr<int> value;
+  std::unique_ptr<int> operator()(const absl::Status&) && {
+    return std::move(value);
+  }
+};
+
+TEST_F(StatusBuilderTest, WithMoveOnlyAdaptor) {
+  StatusBuilder sb(absl::AbortedError("zomg"), absl::SourceLocation());
+  EXPECT_THAT(sb.With(MoveOnlyAdaptor{std::make_unique<int>(100)}),
+              Pointee(100));
+  EXPECT_THAT(StatusBuilder(absl::AbortedError("zomg"), absl::SourceLocation())
+                  .With(MoveOnlyAdaptor{std::make_unique<int>(100)}),
+              Pointee(100));
+}
+
+struct StringifiableType {
+  absl::string_view message;
+
+  template <typename Sink>
+  friend void AbslStringify(Sink& sink, const StringifiableType& o) {
+    sink.Append(o.message);
+  }
+};
+
+class MockLogSink : public absl::LogSink {
+ public:
+  MOCK_METHOD(void, Send, (const absl::LogEntry&), (override));
+};
+
+TEST(WithExtraMessagePolicyTest, AppendsToExtraMessage) {
+  // The policy simply calls operator<< on the builder; the following examples
+  // demonstrate that, without duplicating all of the above tests.
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .With(ExtraMessage("world"))),
+              Eq(absl::AbortedError("hello; world")));
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .With(ExtraMessage() << "world")),
+              Eq(absl::AbortedError("hello; world")));
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .With(ExtraMessage("world"))
+                           .With(ExtraMessage("!"))),
+              Eq(absl::AbortedError("hello; world!")));
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .With(ExtraMessage("world, "))
+                           .SetPrepend()),
+              Eq(absl::AbortedError("world, hello")));
+  EXPECT_THAT(ToStatus(StatusBuilder(absl::AbortedError("hello"),
+                                     absl::SourceLocation())
+                           .With(ExtraMessage() << StringifiableType{"world"})),
+              Eq(absl::AbortedError("hello; world")));
+
+  // The above examples use temporary StatusBuilder rvalues; verify things also
+  // work fine when StatusBuilder is an lvalue.
+  StatusBuilder builder(absl::AbortedError("hello"), absl::SourceLocation());
+  EXPECT_THAT(
+      ToStatus(builder.With(ExtraMessage("world")).With(ExtraMessage("!"))),
+      Eq(absl::AbortedError("hello; world!")));
+}
+
+TEST(WithExtraMessagePolicyTest,
+     ExtraMessageStreamOperatorPreservesRvalueness) {
+  static_assert(
+      std::is_same_v<ExtraMessage&&, decltype(ExtraMessage() << "foo")>);
+}
+
+TEST_F(StatusBuilderTest, StatusSourceLocationChaining) {
+  {
+    absl::Status src = absl::OkStatus();
+    CheckSourceLocation(src);
+    CheckSourceLocation(ToStatus(StatusBuilder(src, absl::SourceLocation())));
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current())));
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current()) << "hmm"));
+  }
+  {
+    absl::Status src = absl::Status(absl::StatusCode::kCancelled, "");
+    CheckSourceLocation(src);
+    CheckSourceLocation(ToStatus(StatusBuilder(src, absl::SourceLocation())));
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current())));
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current()) << ""));
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current()) << "hmm"),
+        {__builtin_LINE() - 1});
+  }
+  {
+    absl::Status src = absl::Status(absl::StatusCode::kCancelled, "msg",
+                                    absl::SourceLocation());
+    CheckSourceLocation(src);
+    CheckSourceLocation(ToStatus(StatusBuilder(src, absl::SourceLocation())));
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current())),
+        {__builtin_LINE() - 1});
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current()) << "hmm"),
+        {__builtin_LINE() - 1});
+  }
+  {
+    absl::Status src = absl::Status(absl::StatusCode::kCancelled, "msg");
+    int src_line = __builtin_LINE() - 1;
+    CheckSourceLocation(src, {src_line});
+    CheckSourceLocation(ToStatus(StatusBuilder(src, absl::SourceLocation())),
+                        {src_line});
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current())),
+        {src_line, __builtin_LINE() - 1});
+    CheckSourceLocation(
+        ToStatus(StatusBuilder(src, absl::SourceLocation::current()) << "hmm"),
+        {src_line, __builtin_LINE() - 1});
+  }
+}
+
+TEST_F(StatusBuilderTest, SetErrorCode) {
+  StatusBuilder builder;
+  builder.SetCode(absl::StatusCode::kResourceExhausted);
+  LOG(INFO) << "Builder code: " << builder;
+  EXPECT_FALSE(builder.ok());
+  EXPECT_EQ(builder.code(), absl::StatusCode::kResourceExhausted);
+}
+
+TEST_F(StatusBuilderTest, BuilderToStatusOrStatusShouldGiveErrorStatusOr) {
+  absl::StatusOr<absl::Status> value = StatusBuilder(absl::CancelledError());
+  ASSERT_FALSE(value.ok());
+  EXPECT_THAT(value.status(), StatusIs(absl::StatusCode::kCancelled));
+}
+
+}  // namespace
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/absl/status/status_macros.h b/absl/status/status_macros.h
new file mode 100644
index 0000000..82e0dc7
--- /dev/null
+++ b/absl/status/status_macros.h
@@ -0,0 +1,474 @@
+// Copyright 2026 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: status_macros.h
+// -----------------------------------------------------------------------------
+//
+// Helper macros and methods to return and propagate errors with `absl::Status`.
+
+#ifndef ABSL_STATUS_STATUS_MACROS_H_
+#define ABSL_STATUS_STATUS_MACROS_H_
+
+#include <cstddef>
+#include <type_traits>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/status/status.h"
+#include "absl/status/status_builder.h"  // IWYU pragma: export
+#include "absl/status/statusor.h"
+#include "absl/types/source_location.h"
+
+// Evaluates an expression that produces a `absl::Status`. If the status is not
+// ok, returns it from the current function.
+//
+// For example:
+//   absl::Status MultiStepFunction() {
+//     ABSL_RETURN_IF_ERROR(Function(args...));
+//     ABSL_RETURN_IF_ERROR(foo.Method(args...));
+//     return absl::OkStatus();
+//   }
+//
+// The macro ends with a `absl::StatusBuilder` which allows the returned status
+// to be extended with more details.  Any chained expressions after the macro
+// will not be evaluated unless there is an error.
+//
+// For example:
+//   absl::Status MultiStepFunction() {
+//     ABSL_RETURN_IF_ERROR(Function(args...)) << "in MultiStepFunction";
+//     ABSL_RETURN_IF_ERROR(foo.Method(args...)).Log(absl::LogSeverity::kError)
+//         << "while processing query: " << query.DebugString();
+//     return absl::OkStatus();
+//   }
+//
+// `absl::StatusBuilder` supports adapting the builder chain using a `With`
+// method and a functor.  This allows for powerful extensions to the macro.
+//
+// For example, teams can define local policies to use across their code:
+//
+//   StatusBuilder TeamPolicy(StatusBuilder builder) {
+//     return std::move(builder.Log(absl::LogSeverity::kWarning).Attach(...));
+//   }
+//
+//   ABSL_RETURN_IF_ERROR(foo()).With(TeamPolicy);
+//   ABSL_RETURN_IF_ERROR(bar()).With(TeamPolicy);
+//
+// Changing the return type allows the macro to be used with Task and Rpc
+// interfaces.  See `util::TaskReturn` and `rpc::RpcSetStatus` for details.
+//
+//   void Read(StringPiece name, util::Task* task) {
+//     int64 id;
+//     ABSL_RETURN_IF_ERROR(GetIdForName(name, &id)).With(TaskReturn(task));
+//     ABSL_RETURN_IF_ERROR(ReadForId(id)).With(TaskReturn(task));
+//     task->Return();
+//   }
+//
+// If using this macro inside a lambda, you need to annotate the return type
+// to avoid confusion between a `absl::StatusBuilder` and a `absl::Status` type.
+// E.g.
+//
+//   []() -> absl::Status {
+//     ABSL_RETURN_IF_ERROR(Function(args...));
+//     ABSL_RETURN_IF_ERROR(foo.Method(args...));
+//     return absl::OkStatus();
+//   }
+#define ABSL_RETURN_IF_ERROR(expr) \
+  ABSL_INTERNAL_STATUS_MACROS_RETURN_IF_ERROR_IMPL_(return, expr)
+
+// Executes an expression `rexpr` that returns an `absl::StatusOr<T>`. On OK,
+// moves its value into the variable defined by `lhs`, otherwise returns
+// from the current function. By default the error status is returned
+// unchanged, but it may be modified by an `error_expression`. If there is an
+// error, `lhs` is not evaluated; thus any side effects that `lhs` may have
+// only occur in the success case.
+//
+// Interface:
+//
+//   ABSL_ASSIGN_OR_RETURN(lhs, rexpr)
+//   ABSL_ASSIGN_OR_RETURN(lhs, rexpr, error_expression);
+//
+// WARNING: if lhs is parenthesized, the parentheses are removed. See examples
+// for more details.
+//
+// WARNING: expands into multiple statements; it cannot be used in a single
+// statement (e.g. as the body of an if statement without {})!
+//
+// Example: Declaring and initializing a new variable (ValueType can be anything
+//          that can be initialized with assignment--including a const
+//          reference, although that's discouraged by go/totw/107):
+//   ABSL_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(arg));
+//
+// Example: Assigning to an existing variable:
+//   ValueType value;
+//   ABSL_ASSIGN_OR_RETURN(value, MaybeGetValue(arg));
+//
+// Example: Assigning to an expression with side effects:
+//   MyProto data;
+//   ABSL_ASSIGN_OR_RETURN(*data.mutable_str(), MaybeGetValue(arg));
+//   // No field "str" is added on error.
+//
+// Example: Initializing a `std::unique_ptr`.
+//   ABSL_ASSIGN_OR_RETURN(std::unique_ptr<T> ptr, MaybeGetPtr(arg));
+//
+// Example: Initializing a map. Because of C++ preprocessor limitations,
+// the type used in ABSL_ASSIGN_OR_RETURN cannot contain commas, so wrap the
+// lhs in parentheses:
+//   ABSL_ASSIGN_OR_RETURN((absl::flat_hash_map<Foo, Bar> my_map), GetMap());
+// Or use `auto` if the type is obvious enough:
+//   ABSL_ASSIGN_OR_RETURN(auto my_map, GetMap());
+//
+// Example: Assigning to structured bindings (go/totw/169). The same situation
+// with comma as in map, so wrap the statement in parentheses.
+//   ABSL_ASSIGN_OR_RETURN((auto [first, second]), GetPair());
+//
+// If passed, the `error_expression` is evaluated to produce the return
+// value. The expression may reference any variable visible in scope, as
+// well as a `absl::StatusBuilder` object populated with the error and
+// named by a single underscore `_`. The expression typically uses the
+// builder to modify the status and is returned directly in manner similar
+// to ABSL_RETURN_IF_ERROR. The expression may, however, evaluate to any type
+// returnable by the function, including (void). For example:
+//
+// Example: Adjusting the error message.
+//   ABSL_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query),
+//                    _ << "while processing query " << query.DebugString());
+//
+// Example: Logging the error on failure.
+//   ABSL_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query), _.LogError());
+//
+#define ABSL_ASSIGN_OR_RETURN(...) \
+  ABSL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_IMPL_(return, __VA_ARGS__)
+
+// =================================================================
+// == Implementation details, do not rely on anything below here. ==
+// =================================================================
+
+#define ABSL_INTERNAL_STATUS_MACROS_RETURN_IF_ERROR_IMPL_(return_keyword, \
+                                                          expr)           \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_ELSE_BLOCKER_                          \
+  if (auto status_macro_internal_adaptor =                                \
+          absl::status_macro_internal::MacroAdaptor(                      \
+              (expr), absl::SourceLocation::current())) {                 \
+  } else /* NOLINT */                                                     \
+    return_keyword status_macro_internal_adaptor.Consume()
+
+#define ABSL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_IMPL_(return_keyword, \
+                                                           ...)            \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_(                          \
+      (return_keyword, __VA_ARGS__,                                        \
+       ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_,               \
+       ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_))              \
+  (return_keyword, __VA_ARGS__)
+
+constexpr bool HasPotentialConditionalOperator(const char* lhs, int size) {
+  for (int i = 0; i < size; ++i) {
+    if (lhs[i] == '?') {
+      return true;
+    }
+  }
+  return false;
+}
+
+template <std::size_t N>
+constexpr bool IsEnclosedByParentheses(const char (&lhs)[N]) {
+  if (N < 2) {
+    return false;
+  }
+  return lhs[0] == '(' && lhs[N - 2] == ')';
+}
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace status_macro_internal {
+
+template <typename T, typename EnableIf = void>
+struct IsAllowedStatusOrMacroType : std::false_type {};
+
+template <typename T>
+struct IsAllowedStatusOrMacroType<
+    T, std::enable_if_t<std::is_convertible_v<
+           T*, typename absl::StatusOr<typename T::value_type>*>>>
+    : std::true_type {};
+
+}  // namespace status_macro_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+// MSVC incorrectly expands variadic macros, splice together a macro call to
+// work around the bug.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_(_1, _2, _3, _4, \
+                                                              NAME, ...)      \
+  NAME
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_(args) \
+  /* NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat) */    \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_ args
+
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_(return_keyword,   \
+                                                             lhs, rexpr)       \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(                          \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__),    \
+      lhs, rexpr,                                                              \
+      return_keyword absl::Status(                                             \
+          std::move(ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, \
+                                                             __LINE__))        \
+              .status(),                                                       \
+          absl::SourceLocation::current()))
+
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_(                  \
+    return_keyword, lhs, rexpr, error_expression)                              \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(                          \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__),    \
+      lhs, rexpr, /* NOLINTNEXTLINE(misc-const-correctness) */                 \
+      absl::StatusBuilder _(                                                   \
+          std::move(ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, \
+                                                             __LINE__))        \
+              .status(),                                                       \
+          absl::SourceLocation::current());                                    \
+      (void)_; /* error_expression is allowed to not use this variable */      \
+      return_keyword(error_expression))
+
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(                 \
+    statusor, lhs, rexpr, error_expression)                                 \
+  auto statusor = (rexpr);                                                  \
+  if (ABSL_PREDICT_FALSE(!statusor.ok())) {                                 \
+    error_expression;                                                       \
+  }                                                                         \
+  {                                                                         \
+    static_assert(                                                          \
+        !IsEnclosedByParentheses(#lhs) ||                                   \
+            !HasPotentialConditionalOperator(#lhs, sizeof(#lhs) - 2),       \
+        "Identified potential conditional operator, consider not "          \
+        "using ABSL_ASSIGN_OR_RETURN");                                     \
+  }                                                                         \
+  {                                                                         \
+    static_assert(                                                          \
+        absl::status_macro_internal::IsAllowedStatusOrMacroType<            \
+            typename std::remove_const<decltype(statusor)>::type>(),        \
+        "ABSL_ASSIGN_OR_RETURN should only be used with absl::StatusOr<>"); \
+  }                                                                         \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED(lhs) =   \
+      (*std::move(statusor))
+
+// Internal helpers for macro expansion.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_EAT(...)
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_REM(...) __VA_ARGS__
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_EMPTY()
+
+// Internal helpers for emptiness arguments check.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER(...) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER_HELPER((__VA_ARGS__, 0, 1))
+// MSVC expands variadic macros incorrectly, so we need this extra indirection
+// to work around that (b/110959038).
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER_HELPER(args) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER_I args
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER_I(e0, e1, is_empty, \
+                                                          ...)              \
+  is_empty
+
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY(...) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_I(__VA_ARGS__)
+
+#if !defined(_MSC_VER) || defined(__clang__) || \
+    (defined(_MSVC_TRADITIONAL) && !_MSVC_TRADITIONAL)
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_I(...) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER(_ __VA_OPT__(, )##__VA_ARGS__)
+#else
+// Nonstandard hack that works for MSVC's legacy preprocessor
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_I(...) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_INNER(_, ##__VA_ARGS__)
+#endif
+
+// Internal helpers for if statement.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IF_1(_Then, _Else) _Then
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IF_0(_Then, _Else) _Else
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IF(_Cond, _Then, _Else) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(                      \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_IF_, _Cond)(_Then, _Else)
+
+// Expands to 1 if the input is parenthesized. Otherwise expands to 0.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_PARENTHESIZED(...) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY(                   \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_EAT __VA_ARGS__)
+
+// If the input is parenthesized, removes the parentheses. Otherwise expands to
+// the input unchanged.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED(...) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_IF(                                        \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_PARENTHESIZED(__VA_ARGS__),         \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_REM,                                   \
+      ABSL_INTERNAL_STATUS_MACROS_IMPL_EMPTY())                               \
+  __VA_ARGS__
+
+// Internal helper for concatenating macro values.
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) x##y
+
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(x, y) \
+  ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y)
+
+// The GNU compiler emits a warning for code like:
+//
+//   if (foo)
+//     if (bar) { } else baz;
+//
+// because it thinks you might want the else to bind to the first if.  This
+// leads to problems with code like:
+//
+//   if (do_expr) ABSL_RETURN_IF_ERROR(expr) << "Some message";
+//
+// The "switch (0) case 0:" idiom is used to suppress this.
+// TODO(b/491833032): Remove this once all users and redefinitions are updated.
+#define STATUS_MACROS_IMPL_ELSE_BLOCKER_ \
+  switch (0)                             \
+  case 0:                                \
+  default:  // NOLINT
+#define ABSL_INTERNAL_STATUS_MACROS_IMPL_ELSE_BLOCKER_ \
+  switch (0)                                           \
+  case 0:                                              \
+  default:  // NOLINT
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace status_macro_internal {
+
+// Provides a conversion to bool so that it can be used inside an if statement
+// that declares a variable.
+class StatusAdaptorForMacros {
+ public:
+  StatusAdaptorForMacros(
+      const absl::Status& status,
+      absl::SourceLocation loc = absl::SourceLocation::current())
+      : builder_(status, loc) {}
+
+  StatusAdaptorForMacros(
+      absl::Status&& status,
+      absl::SourceLocation loc = absl::SourceLocation::current())
+      : builder_(std::move(status), loc) {}
+
+  StatusAdaptorForMacros(const StatusBuilder& builder,
+                         absl::SourceLocation = absl::SourceLocation())
+      : builder_(builder) {}
+
+  StatusAdaptorForMacros(StatusBuilder&& builder,
+                         absl::SourceLocation = absl::SourceLocation())
+      : builder_(std::move(builder)) {}
+
+  StatusAdaptorForMacros(const StatusAdaptorForMacros&) = delete;
+  StatusAdaptorForMacros& operator=(const StatusAdaptorForMacros&) = delete;
+
+  explicit operator bool() const { return ABSL_PREDICT_TRUE(builder_.ok()); }
+
+  StatusBuilder&& Consume() { return std::move(builder_); }
+
+ private:
+  StatusBuilder builder_;
+};
+
+// Special adaptor for use by ABSL_RETURN_IF_ERROR for absl::Status arguments.
+// This one avoids constructing a StatusBuilder on the fast path.
+//
+// REQUIRES: Only used by ABSL_RETURN_IF_ERROR implementation.
+class ReturnIfErrorAdaptor {
+ public:
+  explicit ReturnIfErrorAdaptor(
+      const absl::Status& status,
+      absl::SourceLocation loc = absl::SourceLocation::current())
+      : status_(status), loc_(loc) {}
+
+  explicit ReturnIfErrorAdaptor(
+      absl::Status&& status,
+      absl::SourceLocation loc = absl::SourceLocation::current())
+      : status_(std::move(status)), loc_(loc) {}
+
+  ~ReturnIfErrorAdaptor() {
+    // WARNING! WARNING! WARNING!
+    //
+    // We play fast and loose here and avoid destroying status_. This should be
+    // safe because status_ will never own memory at destruction time. The two
+    // cases to consider are:
+    //  (1) OK: OkStatus() representation needs no cleanup
+    //  (2) Not-OK: we take the else branch in ABSL_RETURN_IF_ERROR and move
+    //      status_ into StatusBuilder which leaves status_ with a MovedFromRep
+    //      that needs no cleanup.
+    // If the absl::Status implementation changes, leaks should be caught by
+    // the various tests we have when run under lsan or debug leak checker.
+  }
+
+  explicit operator bool() const { return ABSL_PREDICT_TRUE(status_.ok()); }
+
+  StatusBuilder Consume() { return StatusBuilder(std::move(status_), loc_); }
+
+ private:
+  // Place the status inside a union so we can avoid generating unnecessary code
+  // to call the Status destructor.
+  union {
+    absl::Status status_;
+    char nothing_[1];
+  };
+  absl::SourceLocation loc_;
+};
+
+// Overloads of MacroAdaptor that pick the right adaptor class
+// for each argument type.
+//
+// TODO(b/501387693): Replace these with deduction guides of template
+// specializations once the bug is fixed. (See prior file revision.)
+inline ReturnIfErrorAdaptor MacroAdaptor(const absl::Status& s,
+                                         absl::SourceLocation loc) {
+  return ReturnIfErrorAdaptor(s, loc);
+}
+inline ReturnIfErrorAdaptor MacroAdaptor(absl::Status&& s,
+                                         absl::SourceLocation loc) {
+  return ReturnIfErrorAdaptor(std::move(s), loc);
+}
+inline StatusAdaptorForMacros MacroAdaptor(const StatusBuilder& s,
+                                           absl::SourceLocation loc) {
+  return StatusAdaptorForMacros(s, loc);
+}
+inline StatusAdaptorForMacros MacroAdaptor(StatusBuilder&& s,
+                                           absl::SourceLocation loc) {
+  return StatusAdaptorForMacros(std::move(s), loc);
+}
+
+}  // namespace status_macro_internal
+
+// By defining ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS, this library also provides
+// unqualified versions of its macros.
+//
+// Unqualified macro names are likely to collide with those in other projects,
+// and so are not recommended.  Furthermore, this is true for any transitive
+// dependencies of Abseil: it is impossible to be confident that downstream
+// libraries will neither define these macros themselves nor depend on a
+// different library that also defines them.
+//
+// To enable unqualified names despite the caveats, define
+// `ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS` preferably at the command line, e.g.
+// `-DABSL_DEFINE_UNQUALIFIED_STATUS_MACROS`, or `local_defines =
+// ["ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS"]` if using Bazel.
+//
+// These are turned on by default inside Google's internal codebase where their
+// use is historically ubiquitous.  Other OSS Google projects should use the
+// qualified versions.
+//
+#ifdef ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS
+#define ASSIGN_OR_RETURN(...) ABSL_ASSIGN_OR_RETURN(__VA_ARGS__)
+#define RETURN_IF_ERROR(...) ABSL_RETURN_IF_ERROR(__VA_ARGS__)
+#endif  // ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS
+
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_STATUS_STATUS_MACROS_H_
diff --git a/absl/status/status_macros_test.cc b/absl/status/status_macros_test.cc
new file mode 100644
index 0000000..7aaeb43
--- /dev/null
+++ b/absl/status/status_macros_test.cc
@@ -0,0 +1,650 @@
+// Copyright 2026 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/status/status_macros.h"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
+#include "absl/base/optimization.h"
+#include "absl/status/status.h"
+#include "absl/status/status_builder.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/source_location.h"
+
+namespace {
+
+using ::testing::AllOf;
+using ::testing::Eq;
+using ::testing::HasSubstr;
+
+using absl::status_macro_internal::ReturnIfErrorAdaptor;
+using absl::status_macro_internal::StatusAdaptorForMacros;
+static_assert(!std::is_default_constructible_v<ReturnIfErrorAdaptor>);
+static_assert(!std::is_default_constructible_v<StatusAdaptorForMacros>);
+static_assert(!std::is_copy_constructible_v<ReturnIfErrorAdaptor>);
+static_assert(!std::is_copy_constructible_v<StatusAdaptorForMacros>);
+static_assert(!std::is_copy_assignable_v<ReturnIfErrorAdaptor>);
+static_assert(!std::is_copy_assignable_v<StatusAdaptorForMacros>);
+
+absl::Status ReturnOk() { return absl::OkStatus(); }
+
+absl::StatusBuilder ReturnOkBuilder() {
+  return absl::StatusBuilder(absl::OkStatus());
+}
+
+absl::Status ReturnError(absl::string_view msg) {
+  return absl::Status(absl::StatusCode::kUnknown, msg);
+}
+
+absl::StatusBuilder ReturnErrorBuilder(absl::string_view msg) {
+  return absl::StatusBuilder(absl::Status(absl::StatusCode::kUnknown, msg));
+}
+
+absl::StatusOr<int> ReturnStatusOrValue(int v) { return v; }
+
+absl::StatusOr<int> ReturnStatusOrError(absl::string_view msg) {
+  return absl::Status(absl::StatusCode::kUnknown, msg);
+}
+
+template <class... Args>
+absl::StatusOr<std::tuple<Args...>> ReturnStatusOrTupleValue(Args&&... v) {
+  return std::tuple<Args...>(std::forward<Args>(v)...);
+}
+
+template <class... Args>
+absl::StatusOr<std::tuple<Args...>> ReturnStatusOrTupleError(
+    absl::string_view msg) {
+  return absl::Status(absl::StatusCode::kUnknown, msg);
+}
+
+absl::StatusOr<int&> ReturnStatusOrRef(int& v) { return v; }
+
+absl::StatusOr<std::unique_ptr<int>> ReturnStatusOrPtrValue(int v) {
+  return std::make_unique<int>(v);
+}
+void CheckSourceLocation(
+    const absl::Status& status, std::vector<int> lines = {},
+    absl::SourceLocation loc = absl::SourceLocation::current()) {
+  ASSERT_EQ(status.GetSourceLocations().size(), lines.size())
+      << "Size check failed at " << loc.line();
+  for (size_t i = 0; i < lines.size(); ++i) {
+    EXPECT_EQ(absl::string_view(status.GetSourceLocations()[i].file_name()),
+              absl::string_view(loc.file_name()))
+        << "File name check failed at " << loc.line();
+    EXPECT_EQ(status.GetSourceLocations()[i].line(), lines[i])
+        << "Line check failed at " << loc.line();
+  }
+}
+TEST(AssignOrReturn, Works) {
+  auto func = []() -> absl::Status {
+    ABSL_ASSIGN_OR_RETURN(int value1, ReturnStatusOrValue(1));
+    EXPECT_EQ(1, value1);
+    ABSL_ASSIGN_OR_RETURN(const int value2, ReturnStatusOrValue(2));
+    EXPECT_EQ(2, value2);
+    ABSL_ASSIGN_OR_RETURN(const int& value3, ReturnStatusOrValue(3));
+    EXPECT_EQ(3, value3);
+    ABSL_ASSIGN_OR_RETURN(int value4 [[maybe_unused]],
+                          ReturnStatusOrError("EXPECTED"));
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(AssignOrReturn, WorksWithReferences) {
+  int value = 17;
+  auto func = [&]() -> absl::Status {
+    ABSL_ASSIGN_OR_RETURN(int& value1, ReturnStatusOrRef(value));
+    EXPECT_EQ(&value1, &value);
+
+    ABSL_ASSIGN_OR_RETURN(const int& value2, ReturnStatusOrRef(value));
+    EXPECT_EQ(&value2, &value);
+
+    ABSL_ASSIGN_OR_RETURN(int value3, ReturnStatusOrRef(value));
+    EXPECT_EQ(value3, value);
+
+    value = 11;
+    EXPECT_NE(value3, value);
+
+    ABSL_ASSIGN_OR_RETURN(int value4 [[maybe_unused]],
+                          ReturnStatusOrError("EXPECTED"));
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(AssignOrReturn, WorksWithCommasInType) {
+#if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
+  GTEST_SKIP() << "Comma support on MSVC requires /Zc:preprocessor";
+#else
+  auto func = []() -> absl::Status {
+    ABSL_ASSIGN_OR_RETURN((std::tuple<int, int> t1),
+                          ReturnStatusOrTupleValue(1, 1));
+    EXPECT_EQ((std::tuple{1, 1}), t1);
+    ABSL_ASSIGN_OR_RETURN((const std::tuple<int, std::tuple<int, int>, int> t2),
+                          ReturnStatusOrTupleValue(1, std::tuple{1, 1}, 1));
+    EXPECT_EQ((std::tuple{1, std::tuple{1, 1}, 1}), t2);
+    ABSL_ASSIGN_OR_RETURN(
+        (std::tuple<int, std::tuple<int, int>, int> t3),
+        (ReturnStatusOrTupleError<int, std::tuple<int, int>, int>("EXPECTED")));
+    t3 = {};  // fix unused error
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+#endif
+}
+
+TEST(AssignOrReturn, WorksWithStructureBindings) {
+#if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
+  GTEST_SKIP() << "Comma support on MSVC requires /Zc:preprocessor";
+#else
+  auto func = []() -> absl::Status {
+    ABSL_ASSIGN_OR_RETURN(
+        (const auto& [t1, t2, t3, t4, t5]),
+        ReturnStatusOrTupleValue(std::tuple{1, 1}, 1, 2, 3, 4));
+    EXPECT_EQ((std::tuple{1, 1}), t1);
+    EXPECT_EQ(1, t2);
+    EXPECT_EQ(2, t3);
+    EXPECT_EQ(3, t4);
+    EXPECT_EQ(4, t5);
+    ABSL_ASSIGN_OR_RETURN(int t6 [[maybe_unused]],
+                          ReturnStatusOrError("EXPECTED"));
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+#endif
+}
+
+TEST(AssignOrReturn, WorksWithParenthesesAndDereference) {
+#if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
+  GTEST_SKIP() << "Comma support on MSVC requires /Zc:preprocessor";
+#else
+  auto func = []() -> absl::Status {
+    int integer;
+    int* pointer_to_integer = &integer;
+    ABSL_ASSIGN_OR_RETURN((*pointer_to_integer), ReturnStatusOrValue(1));
+    EXPECT_EQ(1, integer);
+    ABSL_ASSIGN_OR_RETURN(*pointer_to_integer, ReturnStatusOrValue(2));
+    EXPECT_EQ(2, integer);
+    // Make the test where the order of dereference matters and treat the
+    // parentheses.
+    pointer_to_integer--;
+    int** pointer_to_pointer_to_integer = &pointer_to_integer;
+    ABSL_ASSIGN_OR_RETURN((*pointer_to_pointer_to_integer)[1],
+                          ReturnStatusOrValue(3));
+    EXPECT_EQ(3, integer);
+    ABSL_ASSIGN_OR_RETURN(int t1 [[maybe_unused]],
+                          ReturnStatusOrError("EXPECTED"));
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+#endif
+}
+
+TEST(AssignOrReturn, WorksWithAppend) {
+  auto fail_test_if_called = []() -> std::string {
+    ADD_FAILURE();
+    return "FAILURE";
+  };
+  auto func = [&]() -> absl::Status {
+    int value [[maybe_unused]];
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrValue(1),
+                          _ << fail_test_if_called());
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrError("EXPECTED A"),
+                          _ << "EXPECTED B");
+    return ReturnOk();
+  };
+
+  EXPECT_THAT(func().message(),
+              AllOf(HasSubstr("EXPECTED A"), HasSubstr("EXPECTED B")));
+}
+
+TEST(AssignOrReturn, WorksWithAdaptorFunc) {
+  auto fail_test_if_called = [](absl::StatusBuilder builder) {
+    ADD_FAILURE();
+    return builder;
+  };
+  auto adaptor = [](absl::StatusBuilder builder) {
+    return builder << "EXPECTED B";
+  };
+  auto func = [&]() -> absl::Status {
+    int value [[maybe_unused]];
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrValue(1),
+                          fail_test_if_called(_));
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrError("EXPECTED A"), adaptor(_));
+    return ReturnOk();
+  };
+
+  EXPECT_THAT(func().message(),
+              AllOf(HasSubstr("EXPECTED A"), HasSubstr("EXPECTED B")));
+}
+
+TEST(AssignOrReturn, WorksWithThirdArgumentAndCommas) {
+#if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
+  GTEST_SKIP() << "Comma support on MSVC requires /Zc:preprocessor";
+#else
+  auto fail_test_if_called = [](absl::StatusBuilder builder) {
+    ADD_FAILURE();
+    return builder;
+  };
+  auto adaptor = [](absl::StatusBuilder builder) {
+    return builder << "EXPECTED B";
+  };
+  auto func = [&]() -> absl::Status {
+    ABSL_ASSIGN_OR_RETURN((const auto& [t1, t2, t3]),
+                          ReturnStatusOrTupleValue(1, 2, 3),
+                          fail_test_if_called(_));
+    EXPECT_EQ(t1, 1);
+    EXPECT_EQ(t2, 2);
+    EXPECT_EQ(t3, 3);
+    ABSL_ASSIGN_OR_RETURN(
+        (const auto& [t4, t5, t6]),
+        (ReturnStatusOrTupleError<int, int, int>("EXPECTED A")), adaptor(_));
+    // Silence errors about the unused values.
+    static_cast<void>(t4);
+    static_cast<void>(t5);
+    static_cast<void>(t6);
+    return ReturnOk();
+  };
+
+  EXPECT_THAT(func().message(),
+              AllOf(HasSubstr("EXPECTED A"), HasSubstr("EXPECTED B")));
+#endif
+}
+
+TEST(AssignOrReturn, WorksWithAppendIncludingLocals) {
+  auto func = [&](absl::string_view str) -> absl::Status {
+    int value [[maybe_unused]];
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrError("EXPECTED A"), _ << str);
+    return ReturnOk();
+  };
+
+  EXPECT_THAT(func("EXPECTED B").message(),
+              AllOf(HasSubstr("EXPECTED A"), HasSubstr("EXPECTED B")));
+}
+
+TEST(AssignOrReturn, WorksForExistingVariable) {
+  auto func = []() -> absl::Status {
+    int value = 1;
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrValue(2));
+    EXPECT_EQ(2, value);
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrValue(3));
+    EXPECT_EQ(3, value);
+    ABSL_ASSIGN_OR_RETURN(value, ReturnStatusOrError("EXPECTED"));
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(AssignOrReturn, UniquePtrWorks) {
+  auto func = []() -> absl::Status {
+    ABSL_ASSIGN_OR_RETURN(std::unique_ptr<int> ptr, ReturnStatusOrPtrValue(1));
+    EXPECT_EQ(*ptr, 1);
+    return ReturnError("EXPECTED");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(AssignOrReturn, UniquePtrWorksForExistingVariable) {
+  auto func = []() -> absl::Status {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, ReturnStatusOrPtrValue(1));
+    EXPECT_EQ(*ptr, 1);
+
+    ABSL_ASSIGN_OR_RETURN(ptr, ReturnStatusOrPtrValue(2));
+    EXPECT_EQ(*ptr, 2);
+    return ReturnError("EXPECTED");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(AssignOrReturn, ChainSourceLocation) {
+  auto func1 = []() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, ReturnStatusOrPtrValue(1));
+    return ptr;
+  };
+  auto func2 = []() -> absl::StatusOr<std::unique_ptr<int>> {
+    return absl::Status(absl::StatusCode::kInternal, "msg");
+  };
+  int func2_line = __builtin_LINE() - 2;
+
+  auto func3 = [=]() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, func1());
+    ABSL_ASSIGN_OR_RETURN(ptr, func2());
+    return ptr;
+  };
+  int func3_line = __builtin_LINE() - 3;
+
+  auto func4 = [=]() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, func3());
+    ABSL_ASSIGN_OR_RETURN(ptr, func2());
+    return ptr;
+  };
+  int func4_line = __builtin_LINE() - 4;
+
+  absl::StatusOr<std::unique_ptr<int>> result = func4();
+  EXPECT_EQ(absl::StatusCode::kInternal, result.status().code());
+  CheckSourceLocation(result.status(), {func2_line, func3_line, func4_line});
+}
+
+TEST(AssignOrReturn, NotChainSourceLocationWithEmptyMsg) {
+  auto func1 = []() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, ReturnStatusOrPtrValue(1));
+    return ptr;
+  };
+  auto func2 = []() -> absl::StatusOr<std::unique_ptr<int>> {
+    return absl::Status(absl::StatusCode::kInternal, "");
+  };
+
+  auto func3 = [=]() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, func1());
+    ABSL_ASSIGN_OR_RETURN(ptr, func2());
+    return ptr;
+  };
+
+  auto func4 = [=]() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, func3());
+    ABSL_ASSIGN_OR_RETURN(ptr, func2());
+    return ptr;
+  };
+
+  absl::StatusOr<std::unique_ptr<int>> result = func4();
+  EXPECT_EQ(absl::StatusCode::kInternal, result.status().code());
+  CheckSourceLocation(result.status());
+}
+
+TEST(AssignOrReturn, ChainSourceLocationWith3ArgStatusMacro) {
+  auto func1 = []() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, ReturnStatusOrPtrValue(1));
+    return ptr;
+  };
+  auto func2 = []() -> absl::StatusOr<std::unique_ptr<int>> {
+    return absl::Status(absl::StatusCode::kInternal, "");
+  };
+
+  auto func3 = [=]() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, func1());
+    ABSL_ASSIGN_OR_RETURN(ptr, func2(), _ << "hmm");
+    return ptr;
+  };
+  int func3_line = __builtin_LINE() - 3;
+
+  auto func4 = [=]() -> absl::StatusOr<std::unique_ptr<int>> {
+    std::unique_ptr<int> ptr;
+    ABSL_ASSIGN_OR_RETURN(ptr, func3());
+    ABSL_ASSIGN_OR_RETURN(ptr, func2());
+    return ptr;
+  };
+  int func4_line = __builtin_LINE() - 4;
+
+  absl::StatusOr<std::unique_ptr<int>> result = func4();
+  EXPECT_EQ(absl::StatusCode::kInternal, result.status().code());
+  CheckSourceLocation(result.status(), {func3_line, func4_line});
+}
+
+TEST(ReturnIfError, Works) {
+  auto func = []() -> absl::Status {
+    ABSL_RETURN_IF_ERROR(ReturnOk());
+    ABSL_RETURN_IF_ERROR(ReturnOk());
+    ABSL_RETURN_IF_ERROR(ReturnError("EXPECTED"));
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(ReturnIfError, WorksWithSourceLocation) {
+  using StatusCode = absl::StatusCode;
+  {
+    auto func = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(StatusCode::kUnknown, "EXPECTED"));
+      return ReturnError("ERROR");
+    };
+    int error_line = __builtin_LINE() - 3;
+    int func_line = error_line;
+
+    EXPECT_THAT(func().message(), Eq("EXPECTED"));
+    CheckSourceLocation(func(), {error_line, func_line});
+  }
+  {
+    auto func1 = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(StatusCode::kUnknown, "EXPECTED"));
+      return ReturnError("ERROR");
+    };
+    int error_line = __builtin_LINE() - 3;
+    int func_line = error_line;
+
+    auto func3 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func1());
+      return ReturnError("ERROR_Func3");
+    };
+    int func3_line = __builtin_LINE() - 3;
+
+    auto func4 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func3());
+      return ReturnError("ERROR_Func4");
+    };
+    int func4_line = __builtin_LINE() - 3;
+    CheckSourceLocation(func4(),
+                        {error_line, func_line, func3_line, func4_line});
+  }
+  {
+    auto func1 = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(StatusCode::kUnknown, ""));
+      return ReturnError("ERROR");
+    };
+
+    auto func3 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func1());
+      return ReturnError("ERROR_Func3");
+    };
+
+    auto func4 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func3());
+      return ReturnError("ERROR_Func4");
+    };
+    CheckSourceLocation(func4());
+  }
+}
+
+TEST(ReturnIfError, WorksWithSourceLocationOn2Arg) {
+  {
+    auto func = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(absl::StatusCode::kUnknown, "EXPECTED"))
+          << "foo";
+      return ReturnError("ERROR");
+    };
+    int error_line = __builtin_LINE() - 4;
+    int func_line = error_line;
+
+    EXPECT_THAT(func().message(), Eq("EXPECTED; foo"));
+    CheckSourceLocation(func(), {error_line, func_line});
+  }
+  {
+    auto func1 = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(absl::StatusCode::kUnknown, "EXPECTED"))
+          << "foo";
+      return ReturnError("ERROR");
+    };
+    int error_line = __builtin_LINE() - 4;
+    int func_line = error_line;
+
+    auto func3 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func1());
+      return ReturnError("ERROR_Func3");
+    };
+    int func3_line = __builtin_LINE() - 3;
+
+    auto func4 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func3());
+      return ReturnError("ERROR_Func4");
+    };
+    int func4_line = __builtin_LINE() - 3;
+    CheckSourceLocation(func4(),
+                        {error_line, func_line, func3_line, func4_line});
+  }
+  {
+    auto func1 = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(absl::StatusCode::kUnknown, ""));
+      return ReturnError("ERROR");
+    };
+
+    auto func3 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func1()) << "foo";
+      return ReturnError("ERROR_Func3");
+    };
+    int func3_line = __builtin_LINE() - 3;
+
+    auto func4 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func3());
+      return ReturnError("ERROR_Func4");
+    };
+    int func4_line = __builtin_LINE() - 3;
+    EXPECT_THAT(func4().message(), Eq("foo"));
+    CheckSourceLocation(func4(), {func3_line, func4_line});
+  }
+  {
+    auto func1 = []() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(ReturnOk());
+      ABSL_RETURN_IF_ERROR(absl::Status(absl::StatusCode::kUnknown, "")) << "";
+      return ReturnError("ERROR");
+    };
+
+    auto func3 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func1());
+      return ReturnError("ERROR_Func3");
+    };
+
+    auto func4 = [=]() -> absl::Status {
+      ABSL_RETURN_IF_ERROR(func3());
+      return ReturnError("ERROR_Func4");
+    };
+    CheckSourceLocation(func4());
+  }
+}
+
+TEST(ReturnIfError, WorksWithBuilder) {
+  auto func = []() -> absl::Status {
+    ABSL_RETURN_IF_ERROR(ReturnOkBuilder());
+    ABSL_RETURN_IF_ERROR(ReturnOkBuilder());
+    ABSL_RETURN_IF_ERROR(ReturnErrorBuilder("EXPECTED"));
+    return ReturnErrorBuilder("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+
+  // Test that ABSL_RETURN_IF_ERROR can also return the StatusBuilder directly.
+  auto func2 = []() -> absl::StatusBuilder {
+    ABSL_RETURN_IF_ERROR(ReturnOkBuilder());
+    ABSL_RETURN_IF_ERROR(ReturnOkBuilder());
+    ABSL_RETURN_IF_ERROR(ReturnErrorBuilder("EXPECTED"));
+    return ReturnErrorBuilder("ERROR");
+  };
+  EXPECT_THAT(static_cast<absl::Status>(func2()).message(), Eq("EXPECTED"));
+}
+
+TEST(ReturnIfError, IfInputIsBuilderDoesNotEagerlyConvertToStatus) {
+  auto func = []() -> absl::Status {
+    auto builder = ReturnErrorBuilder("FIRST");
+    builder.SetPrepend();
+    // If this call decays the builder to Status first and then makes another
+    // builder it will forget about the SetPrepend and the streaming will happen
+    // in the wrong order.
+    ABSL_RETURN_IF_ERROR(builder) << "SECOND ";
+    return absl::OkStatus();
+  };
+  EXPECT_THAT(func().message(), Eq("SECOND FIRST"));
+}
+
+TEST(ReturnIfError, WorksWithLambda) {
+  auto func = []() -> absl::Status {
+    ABSL_RETURN_IF_ERROR([] { return ReturnOk(); }());
+    ABSL_RETURN_IF_ERROR([] { return ReturnError("EXPECTED"); }());
+    return ReturnError("ERROR");
+  };
+
+  EXPECT_THAT(func().message(), Eq("EXPECTED"));
+}
+
+TEST(ReturnIfError, WorksWithAppend) {
+  auto fail_test_if_called = []() -> std::string {
+    ADD_FAILURE();
+    return "FAILURE";
+  };
+  auto func = [&]() -> absl::Status {
+    ABSL_RETURN_IF_ERROR(ReturnOk()) << fail_test_if_called();
+    ABSL_RETURN_IF_ERROR(ReturnError("EXPECTED A")) << "EXPECTED B";
+    return absl::OkStatus();
+  };
+
+  EXPECT_THAT(func().message(),
+              AllOf(HasSubstr("EXPECTED A"), HasSubstr("EXPECTED B")));
+}
+
+TEST(ReturnIfError, WorksWithVoidReturnAdaptor) {
+  int code = 0;
+  int phase = 0;
+  auto adaptor = [&](absl::Status status) -> void { code = phase; };
+  auto func = [&]() -> void {
+    phase = 1;
+    ABSL_RETURN_IF_ERROR(ReturnOk()).With(adaptor);
+    phase = 2;
+    ABSL_RETURN_IF_ERROR(ReturnError("EXPECTED A")).With(adaptor);
+    phase = 3;
+  };
+
+  func();
+  EXPECT_EQ(phase, 2);
+  EXPECT_EQ(code, 2);
+}
+
+}  // namespace
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 25af3f2..805cfc2 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -434,6 +434,7 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = [
         "//absl:friends",
+        "//absl/status:__pkg__",
         "//visibility:private",
     ],
     deps = [
diff --git a/absl/types/any.h b/absl/types/any.h
index 9026b1b..accb025 100644
--- a/absl/types/any.h
+++ b/absl/types/any.h
@@ -25,6 +25,7 @@
 #define ABSL_TYPES_ANY_H_
 
 #include <any>  // IWYU pragma: export
+#include <initializer_list>
 
 #include "absl/base/config.h"
 
@@ -35,10 +36,30 @@
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
+
 using any ABSL_DEPRECATE_AND_INLINE() = std::any;
-using std::any_cast;
+
+template <typename T, typename... Args>
+[[deprecated]] constexpr decltype(std::any_cast<T>(std::declval<Args>()...))
+any_cast(Args&&... args) {
+  return std::any_cast<T>(std::forward<Args>(args)...);
+}
+
 using bad_any_cast ABSL_DEPRECATE_AND_INLINE() = std::bad_any_cast;
-using std::make_any;
+
+template <typename T, typename... Args>
+[[deprecated]] constexpr decltype(std::make_any<T>(std::declval<Args>()...))
+make_any(Args&&... args) {
+  return std::make_any<T>(std::forward<Args>(args)...);
+}
+
+template <typename T, typename U, typename... Args>
+[[deprecated]] constexpr decltype(std::make_any<T>(
+    std::declval<std::initializer_list<U>>(), std::declval<Args>()...))
+make_any(std::initializer_list<U> il, Args&&... args) {
+  return std::make_any<T>(il, std::forward<Args>(args)...);
+}
+
 ABSL_NAMESPACE_END
 }  // namespace absl
 
diff --git a/absl/types/optional.h b/absl/types/optional.h
index 96197ab..c70efb1 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -23,6 +23,7 @@
 #ifndef ABSL_TYPES_OPTIONAL_H_
 #define ABSL_TYPES_OPTIONAL_H_
 
+#include <initializer_list>
 #include <optional>
 
 #include "absl/base/config.h"
@@ -35,7 +36,26 @@
 using bad_optional_access ABSL_REFACTOR_INLINE
     = std::bad_optional_access;
 
-using std::make_optional;
+template <typename T>
+ABSL_REFACTOR_INLINE constexpr decltype(std::make_optional(
+    std::declval<T>())) make_optional(T&& value) {
+  return std::make_optional(std::forward<T>(value));
+}
+
+template <typename T, typename... Args>
+constexpr decltype(std::make_optional<T>(
+    std::declval<Args>()...)) make_optional(Args&&... args) {
+  return std::make_optional<T>(std::forward<Args>(args)...);
+}
+
+template <typename T, typename U, typename... Args>
+constexpr decltype(std::make_optional<T>(
+    std::declval<std::initializer_list<U>>(),
+    std::declval<Args>()...)) make_optional(std::initializer_list<U> il,
+                                            Args&&... args) {
+  return std::make_optional<T>(il, std::forward<Args>(args)...);
+}
+
 using std::nullopt;
 
 using nullopt_t ABSL_REFACTOR_INLINE
diff --git a/absl/types/variant.h b/absl/types/variant.h
index fd90c63..49f3e24 100644
--- a/absl/types/variant.h
+++ b/absl/types/variant.h
@@ -37,9 +37,36 @@
 using bad_variant_access ABSL_REFACTOR_INLINE
     = std::bad_variant_access;
 
-using std::get;
-using std::get_if;
-using std::holds_alternative;
+template <size_t I, typename... Args>
+[[deprecated]] constexpr auto get(Args&&... args)
+    -> decltype(std::get<I>(std::forward<Args>(args)...)) {
+  return std::get<I>(std::forward<Args>(args)...);
+}
+
+template <typename T, typename... Args>
+[[deprecated]] constexpr decltype(std::get<T>(std::declval<Args>()...)) get(
+    Args&&... args) {
+  return std::get<T>(std::forward<Args>(args)...);
+}
+
+template <size_t I, typename... Args>
+[[deprecated]] constexpr decltype(std::get_if<I>(std::declval<Args>()...))
+get_if(Args&&... args) {
+  return std::get_if<I>(std::forward<Args>(args)...);
+}
+
+template <typename T, typename... Args>
+[[deprecated]] constexpr decltype(std::get_if<T>(std::declval<Args>()...))
+get_if(Args&&... args) {
+  return std::get_if<T>(std::forward<Args>(args)...);
+}
+
+template <typename T, typename... Args>
+[[deprecated]] constexpr decltype(std::holds_alternative<T>(
+    std::declval<Args>()...))
+holds_alternative(Args&&... args) {
+  return std::holds_alternative<T>(std::forward<Args>(args)...);
+}
 
 using monostate ABSL_REFACTOR_INLINE
     = std::monostate;
@@ -67,7 +94,11 @@
 inline constexpr size_t variant_size_v ABSL_REFACTOR_INLINE
     = std::variant_size_v<T>;
 
-using std::visit;
+template <typename... Args>
+[[deprecated]] constexpr decltype(std::visit(std::declval<Args>()...)) visit(
+    Args&&... args) {
+  return std::visit(std::forward<Args>(args)...);
+}
 
 namespace variant_internal {
 // Helper visitor for converting a variant<Ts...>` into another type (mostly
diff --git a/absl/utility/utility.h b/absl/utility/utility.h
index 4dbc01c..dd699d4 100644
--- a/absl/utility/utility.h
+++ b/absl/utility/utility.h
@@ -18,8 +18,10 @@
 #include <cstddef>
 #include <cstdlib>
 #include <tuple>
+#include <type_traits>
 #include <utility>
 
+#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/macros.h"
 
@@ -35,9 +37,34 @@
 // abstractions for platforms that had not yet provided them. Those
 // platforms are no longer supported. New code should simply use the
 // the ones from std directly.
-using std::apply;
-using std::exchange;
-using std::forward;
+template <class F, class T>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr decltype(auto)
+    apply(F&& f, T&& t) noexcept(noexcept(std::apply(std::declval<F>(),
+                                                     std::declval<T>()))) {
+  return std::apply(std::forward<F>(f), std::forward<T>(t));
+}
+
+template <class T1, class T2 = T1>
+ABSL_DEPRECATE_AND_INLINE()
+constexpr T1 exchange(T1& obj, T2&& new_value) noexcept(
+    noexcept(std::exchange(std::declval<T1&>(), std::declval<T2>()))) {
+  return std::exchange(obj, std::forward<T2>(new_value));
+}
+
+template <class T>
+[[deprecated("Use std::forward instead.")]] [[nodiscard]] constexpr T&& forward(
+    std::remove_reference_t<T>& arg ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept {
+  // NOLINTNEXTLINE: Avoid warnings about T not being the spelled type of arg.
+  return std::forward<T>(arg);
+}
+
+template <class T>
+[[deprecated("Use std::forward instead.")]] [[nodiscard]] constexpr T&& forward(
+    std::remove_reference_t<T>&& arg ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept {
+  // NOLINTNEXTLINE: Avoid warnings about T not being the spelled type of arg.
+  return std::forward<T>(arg);
+}
 
 inline constexpr const std::in_place_t& in_place ABSL_DEPRECATE_AND_INLINE() =
     std::in_place;
@@ -69,7 +96,13 @@
 using index_sequence_for ABSL_DEPRECATE_AND_INLINE() =
     std::index_sequence_for<T...>;
 
-using std::make_from_tuple;
+template <class T, class Tuple>
+ABSL_DEPRECATE_AND_INLINE()
+[[nodiscard]] constexpr decltype(std::make_from_tuple<T>(std::declval<Tuple>()))
+    make_from_tuple(Tuple&& arg) noexcept(
+        noexcept(std::make_from_tuple<T>(std::declval<Tuple>()))) {
+  return std::make_from_tuple<T>(std::forward<Tuple>(arg));
+}
 
 template <size_t N>
 using make_index_sequence ABSL_DEPRECATE_AND_INLINE() =
@@ -79,7 +112,19 @@
 using make_integer_sequence ABSL_DEPRECATE_AND_INLINE() =
     std::make_integer_sequence<T, N>;
 
-using std::move;
+template <class It, class OutIt>
+[[deprecated("Use std::move instead.")]]
+constexpr OutIt move(It&& begin, It&& end, OutIt&& output) {
+  return std::move(std::forward<It>(begin), std::forward<It>(end),
+                   std::forward<OutIt>(output));
+}
+
+template <class T>
+[[deprecated("Use std::move instead.")]]
+[[nodiscard]] constexpr std::remove_reference_t<T>&&
+move(T&& arg ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept {
+  return std::move(arg);  // NOLINT(bugprone-move-forwarding-reference)
+}
 
 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
 // Backfill for std::nontype_t. An instance of this class can be provided as a
diff --git a/ci/linux_arm_clang-latest_libcxx_bazel.sh b/ci/linux_arm_clang-latest_libcxx_bazel.sh
index 4c04c77..24d5e48 100755
--- a/ci/linux_arm_clang-latest_libcxx_bazel.sh
+++ b/ci/linux_arm_clang-latest_libcxx_bazel.sh
@@ -69,7 +69,7 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
         --env="CC=/opt/llvm/bin/clang" \
         --env="BAZEL_CXXOPTS=-std=${std}:-nostdinc++" \
         --env="BAZEL_LINKOPTS=-L/opt/llvm/lib/aarch64-unknown-linux-gnu:-lc++:-lc++abi:-lm:-Wl,-rpath=/opt/llvm/lib/aarch64-unknown-linux-gnu" \
diff --git a/ci/linux_clang-latest_libcxx_asan_bazel.sh b/ci/linux_clang-latest_libcxx_asan_bazel.sh
index 7f36980..b8d2b5f 100755
--- a/ci/linux_clang-latest_libcxx_asan_bazel.sh
+++ b/ci/linux_clang-latest_libcxx_asan_bazel.sh
@@ -72,7 +72,7 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
         --env="CC=/opt/llvm/bin/clang" \
         --env="BAZEL_CXXOPTS=-std=${std}:-nostdinc++" \
         --env="BAZEL_LINKOPTS=-L/opt/llvm/lib/x86_64-unknown-linux-gnu:-lc++:-lc++abi:-lm:-Wl,-rpath=/opt/llvm/lib/x86_64-unknown-linux-gnu" \
diff --git a/ci/linux_clang-latest_libcxx_bazel.sh b/ci/linux_clang-latest_libcxx_bazel.sh
index 47a21ea..99e92b9 100755
--- a/ci/linux_clang-latest_libcxx_bazel.sh
+++ b/ci/linux_clang-latest_libcxx_bazel.sh
@@ -69,7 +69,7 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
         --env="CC=/opt/llvm/bin/clang" \
         --env="BAZEL_CXXOPTS=-std=${std}:-nostdinc++" \
         --env="BAZEL_LINKOPTS=-L/opt/llvm/lib/x86_64-unknown-linux-gnu:-lc++:-lc++abi:-lm:-Wl,-rpath=/opt/llvm/lib/x86_64-unknown-linux-gnu" \
diff --git a/ci/linux_clang-latest_libcxx_tsan_bazel.sh b/ci/linux_clang-latest_libcxx_tsan_bazel.sh
index 235971b..56c3c41 100755
--- a/ci/linux_clang-latest_libcxx_tsan_bazel.sh
+++ b/ci/linux_clang-latest_libcxx_tsan_bazel.sh
@@ -69,11 +69,11 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
         --env="CC=/opt/llvm/bin/clang" \
         --env="BAZEL_CXXOPTS=-std=${std}:-nostdinc++" \
-        --env="BAZEL_LINKOPTS=-L/opt/llvm-tsan/lib/x86_64-unknown-linux-gnu:-lc++:-lc++abi:-lm:-Wl,-rpath=/opt/llvm-tsan/lib/x86_64-unknown-linux-gnu" \
-        --env="CPLUS_INCLUDE_PATH=/opt/llvm-tsan/include/c++/v1:/opt/llvm-tsan/include/x86_64-unknown-linux-gnu/c++/v1/" \
+        --env="BAZEL_LINKOPTS=-L/opt/llvm-tsan/lib:-lc++:-lc++abi:-lgcc_s:-lm:-Wl,-rpath=/opt/llvm-tsan/lib" \
+        --env="CPLUS_INCLUDE_PATH=/opt/llvm-tsan/include/c++/v1" \
         --mount type=bind,source="${ABSEIL_ROOT}",target=/abseil-cpp,readonly \
         --workdir=/abseil-cpp \
         --cap-add=SYS_PTRACE \
diff --git a/ci/linux_clang-latest_libstdcxx_bazel.sh b/ci/linux_clang-latest_libstdcxx_bazel.sh
index 6b9f0b4..2fc8210 100755
--- a/ci/linux_clang-latest_libstdcxx_bazel.sh
+++ b/ci/linux_clang-latest_libstdcxx_bazel.sh
@@ -70,7 +70,7 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
         --env="CC=/opt/llvm/bin/clang" \
         --env="BAZEL_CXXOPTS=-std=${std}" \
         --mount type=bind,source="${ABSEIL_ROOT}",target=/abseil-cpp,readonly \
diff --git a/ci/linux_docker_containers.sh b/ci/linux_docker_containers.sh
index 8cb17f7..7b6e0a8 100644
--- a/ci/linux_docker_containers.sh
+++ b/ci/linux_docker_containers.sh
@@ -16,7 +16,7 @@
 # Test scripts should source this file to get the identifiers.
 
 readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20230612"
-readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20260131"
-readonly LINUX_ARM_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_arm_hybrid-latest:20260131"
-readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20260131"
-readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20260131"
+readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest@sha256:baa99e65a3cc837bab8e5246f1870d25c76d0adf2b1d598ee5a3ec77fd2e19bd"
+readonly LINUX_ARM_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_arm_hybrid-latest@sha256:04479ae67993e1a70dc1730bcddfe3233ac3af178ede0b33044dd9c31b889ac8"
+readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest@sha256:baa99e65a3cc837bab8e5246f1870d25c76d0adf2b1d598ee5a3ec77fd2e19bd"
+readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest@sha256:baa99e65a3cc837bab8e5246f1870d25c76d0adf2b1d598ee5a3ec77fd2e19bd"
diff --git a/ci/linux_gcc-floor_libstdcxx_bazel.sh b/ci/linux_gcc-floor_libstdcxx_bazel.sh
index b1ca8ef..765b784 100755
--- a/ci/linux_gcc-floor_libstdcxx_bazel.sh
+++ b/ci/linux_gcc-floor_libstdcxx_bazel.sh
@@ -41,7 +41,7 @@
 
 # Print information about the environment.
 docker run "${DOCKER_CONTAINER}" /usr/bin/fastfetch -c ci
-docker run "${DOCKER_CONTAINER}" /opt/gcc-9/bin/gcc -v
+docker run "${DOCKER_CONTAINER}" /opt/gcc-10/bin/gcc -v
 docker run "${DOCKER_CONTAINER}" cat /root/cached_bazel_versions
 
 # USE_BAZEL_CACHE=1 only works on Kokoro.
@@ -69,10 +69,10 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
-        --env="CC=/opt/gcc-9/bin/gcc" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
+        --env="CC=/opt/gcc-10/bin/gcc" \
         --env="BAZEL_CXXOPTS=-std=${std}" \
-        --env="BAZEL_LINKOPTS=-L/opt/gcc-9/lib64:-Wl,-rpath=/opt/gcc-9/lib64" \
+        --env="BAZEL_LINKOPTS=-L/opt/gcc-10/lib64:-Wl,-rpath=/opt/gcc-10/lib64" \
         --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \
         --workdir=/abseil-cpp \
         --cap-add=SYS_PTRACE \
diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh
index 86130f5..509aeb9 100755
--- a/ci/linux_gcc-latest_libstdcxx_bazel.sh
+++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh
@@ -69,7 +69,7 @@
     for exceptions_mode in ${EXCEPTIONS_MODE}; do
       echo "--------------------------------------------------------------------"
       time docker run \
-        --env="USE_BAZEL_VERSION=9.0.0" \
+        --env="USE_BAZEL_VERSION=9.1.0" \
         --env="CC=/usr/local/bin/gcc" \
         --env="BAZEL_CXXOPTS=-std=${std}" \
         --mount type=bind,source="${ABSEIL_ROOT}",target=/abseil-cpp-ro,readonly \
diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh
index 1f509bd..54d06eb 100755
--- a/ci/macos_xcode_bazel.sh
+++ b/ci/macos_xcode_bazel.sh
@@ -27,7 +27,7 @@
 fi
 
 # If we are running on Kokoro, check for a versioned Bazel binary.
-KOKORO_GFILE_BAZEL_BIN="bazel-9.0.0-darwin-x86_64"
+KOKORO_GFILE_BAZEL_BIN="bazel-9.1.0-darwin-x86_64"
 if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
   BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
   chmod +x ${BAZEL_BIN}
diff --git a/ci/windows_clangcl_bazel.bat b/ci/windows_clangcl_bazel.bat
index ed5bc5a..42be0f7 100755
--- a/ci/windows_clangcl_bazel.bat
+++ b/ci/windows_clangcl_bazel.bat
@@ -47,7 +47,7 @@
 :: /google/data/rw/teams/absl/kokoro/windows.
 ::
 :: TODO(absl-team): Remove -Wno-microsoft-cast
-%KOKORO_GFILE_DIR%\bazel-9.0.0-windows-x86_64.exe ^
+%KOKORO_GFILE_DIR%\bazel-9.1.0-windows-x86_64.exe ^
   test ... ^
   --compilation_mode=%COMPILATION_MODE% ^
   --compiler=clang-cl ^
diff --git a/ci/windows_msvc_bazel.bat b/ci/windows_msvc_bazel.bat
index f07bbfd..031d08f 100755
--- a/ci/windows_msvc_bazel.bat
+++ b/ci/windows_msvc_bazel.bat
@@ -42,7 +42,7 @@
 :: To upgrade Bazel, first download a new binary from
 :: https://github.com/bazelbuild/bazel/releases and copy it to
 :: /google/data/rw/teams/absl/kokoro/windows.
-"%KOKORO_GFILE_DIR%\bazel-9.0.0-windows-x86_64.exe" ^
+"%KOKORO_GFILE_DIR%\bazel-9.1.0-windows-x86_64.exe" ^
   test ... ^
   --compilation_mode=%COMPILATION_MODE% ^
   --copt=/WX ^