diff --git a/MODULE.bazel b/MODULE.bazel
index 6dfccce..00ab4c3 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -26,8 +26,8 @@
 )
 use_repo(cc_configure, "local_config_cc")
 
-bazel_dep(name = "rules_cc", version = "0.2.18")
-bazel_dep(name = "bazel_skylib", version = "1.9.0")
+bazel_dep(name = "rules_cc", version = "0.2.22")
+bazel_dep(name = "bazel_skylib", version = "1.9.2")
 bazel_dep(name = "platforms", version = "1.1.0")
 
 bazel_dep(
@@ -40,7 +40,7 @@
 # intended to be used by Abseil users depend on GoogleTest.
 bazel_dep(
     name = "googletest",
-    version = "1.17.0.bcr.2",
+    version = "1.18.0",
 )
 
 # Note: Gloop is NOT a dev_dependency, but should never be used directly.  It is only included here
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index bd43e66..6ec0446 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -639,47 +639,16 @@
 //
 // Annotates implicit fall-through between switch labels, allowing a case to
 // indicate intentional fallthrough and turn off warnings about any lack of a
-// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by
-// a semicolon and can be used in most places where `break` can, provided that
-// no statements exist between it and the next switch label.
+// `break` statement.
 //
-// Example:
+// Deprecated: Use the standard C++17 `[[fallthrough]]` instead.
 //
-//  switch (x) {
-//    case 40:
-//    case 41:
-//      if (truth_is_out_there) {
-//        ++x;
-//        ABSL_FALLTHROUGH_INTENDED;  // Use instead of/along with annotations
-//                                    // in comments
-//      } else {
-//        return x;
-//      }
-//    case 42:
-//      ...
-//
-// Notes: When supported, GCC and Clang can issue a warning on switch labels
-// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See
-// clang documentation on language extensions for details:
-// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
-//
-// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has
-// no effect on diagnostics. In any case this macro has no effect on runtime
-// behavior and performance of code.
+// This macro has no effect on runtime behavior and performance of code.
 
 #ifdef ABSL_FALLTHROUGH_INTENDED
 #error "ABSL_FALLTHROUGH_INTENDED should not be defined."
-#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough)
-#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
-#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough)
-#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]]
-#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough)
-#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
-#else
-#define ABSL_FALLTHROUGH_INTENDED \
-  do {                            \
-  } while (0)
 #endif
+#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
 
 // ABSL_DEPRECATED()
 //
diff --git a/absl/base/casts.h b/absl/base/casts.h
index 8aac0da..17cc0b9 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -30,11 +30,9 @@
 #include <typeinfo>
 #include <utility>
 
-#ifdef __has_include
 #if __has_include(<version>)
 #include <version>  // For __cpp_lib_bit_cast.
 #endif
-#endif
 
 #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
 #include <bit>  // For std::bit_cast.
diff --git a/absl/base/config.h b/absl/base/config.h
index 4a35ff1..e3e2c96 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -241,41 +241,6 @@
 #define ABSL_HAVE_TLS 1
 #endif
 
-// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
-//
-// Checks whether `std::is_trivially_destructible<T>` is supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set
-#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
-#endif
-
-// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-//
-// Checks whether `std::is_trivially_default_constructible<T>` and
-// `std::is_trivially_copy_constructible<T>` are supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
-#else
-#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
-#endif
-
-// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
-//
-// Checks whether `std::is_trivially_copy_assignable<T>` is supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot be directly set
-#else
-#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
-#endif
-
-// ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
-//
-// Checks whether `std::is_trivially_copyable<T>` is supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set
-#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
-#endif
-
 // ABSL_HAVE_THREAD_LOCAL
 //
 // Checks whether the `thread_local` storage duration specifier is supported.
@@ -512,14 +477,9 @@
        __cpp_lib_source_location >= 201907L) || \
     (defined(ABSL_INTERNAL_CPLUSPLUS_LANG) &&   \
      ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L)
-#ifdef __has_include
 #if __has_include(<source_location>)
 #define ABSL_HAVE_STD_SOURCE_LOCATION 1
 #endif
-#else
-// No __has_include support, so just assume C++ language version is correct.
-#define ABSL_HAVE_STD_SOURCE_LOCATION 1
-#endif
 #endif
 
 // ABSL_USES_STD_SOURCE_LOCATION
@@ -709,17 +669,6 @@
 #define ABSL_HAVE_LEAK_SANITIZER 1
 #endif
 
-// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
-//
-// Deprecated: always defined to 1.
-// Class template argument deduction is a language feature added in C++17,
-// which means all versions of C++ supported by Abseil have it.
-#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
-#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set."
-#else
-#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1
-#endif
-
 // `ABSL_INTERNAL_HAS_RTTI` determines whether abseil is being compiled with
 // RTTI support.
 #ifdef ABSL_INTERNAL_HAS_RTTI
diff --git a/absl/base/const_init.h b/absl/base/const_init.h
index 16520b6..28dee6f 100644
--- a/absl/base/const_init.h
+++ b/absl/base/const_init.h
@@ -30,8 +30,8 @@
 // undefined behavior, unless their constructors and destructors are designed
 // with this issue in mind.
 //
-// The normal way to deal with this issue in C++11 is to use constant
-// initialization and trivial destructors.
+// The normal way to deal with this issue is to use constant initialization and
+// trivial destructors.
 //
 // Constant initialization is guaranteed to occur before any other code
 // executes.  Constructors that are declared 'constexpr' are eligible for
diff --git a/absl/base/internal/cpu_detect.cc b/absl/base/internal/cpu_detect.cc
index 070cc86..a939bbf 100644
--- a/absl/base/internal/cpu_detect.cc
+++ b/absl/base/internal/cpu_detect.cc
@@ -26,7 +26,7 @@
 #endif
 
 #if defined(__aarch64__) && defined(__APPLE__)
-#if defined(__has_include) && __has_include(<arm/cpu_capabilities_public.h>)
+#if __has_include(<arm/cpu_capabilities_public.h>)
 #include <arm/cpu_capabilities_public.h>
 #endif
 #include <sys/sysctl.h>
diff --git a/absl/base/internal/strerror.cc b/absl/base/internal/strerror.cc
index 519b93f..e9c4c23 100644
--- a/absl/base/internal/strerror.cc
+++ b/absl/base/internal/strerror.cc
@@ -61,7 +61,7 @@
 }
 
 // kSysNerr is the number of errors from a recent glibc. `StrError()` falls back
-// to `StrErrorAdaptor()` if the value is larger than this.
+// to `StrErrorInternal()` if the value is larger than this.
 constexpr int kSysNerr = 135;
 
 std::array<std::string, kSysNerr>* NewStrErrorTable() {
diff --git a/absl/base/internal/tsan_mutex_interface.h b/absl/base/internal/tsan_mutex_interface.h
index 39207d8..e2d3d93 100644
--- a/absl/base/internal/tsan_mutex_interface.h
+++ b/absl/base/internal/tsan_mutex_interface.h
@@ -16,6 +16,8 @@
 // It provides ThreadSanitizer annotations for custom mutexes.
 // See <sanitizer/tsan_interface.h> for meaning of these annotations.
 
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
 #ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
 #define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
 
@@ -30,11 +32,10 @@
 #error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set."
 #endif
 
-#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include)
-#if __has_include(<sanitizer/tsan_interface.h>)
+#if defined(ABSL_HAVE_THREAD_SANITIZER) && \
+    __has_include(<sanitizer/tsan_interface.h>)
 #define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1
 #endif
-#endif
 
 #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
 #include <sanitizer/tsan_interface.h>
diff --git a/absl/base/macros.h b/absl/base/macros.h
index c435ebc..69463f3 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -116,10 +116,9 @@
 
 // ABSL_ASSERT()
 //
-// In C++11, `assert` can't be used portably within constexpr functions.
-// `assert` also generates spurious unused-symbol warnings.
-// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr
-// functions, and maintains references to symbols.  Example:
+// `assert` generates spurious unused-symbol warnings when NDEBUG is defined.
+// ABSL_ASSERT functions as a runtime assert but maintains references to
+// symbols even under NDEBUG.  Example:
 //
 // constexpr double Divide(double a, double b) {
 //   return ABSL_ASSERT(b != 0), a / b;
diff --git a/absl/base/policy_checks.h b/absl/base/policy_checks.h
index 88b5774..45fe3d5 100644
--- a/absl/base/policy_checks.h
+++ b/absl/base/policy_checks.h
@@ -52,7 +52,7 @@
 #error "This package requires Visual Studio 2022 (MSVC++ 17.0) or higher."
 #endif
 
-// We support GCC 7 and later.
+// We support GCC 10 and later.
 // This minimum will go up.
 #if defined(__GNUC__) && !defined(__clang__)
 #if __GNUC__ < 10
diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc
index 6ac2e36..411150a 100644
--- a/absl/base/spinlock_test_common.cc
+++ b/absl/base/spinlock_test_common.cc
@@ -127,7 +127,7 @@
 }
 
 #ifndef ABSL_HAVE_THREAD_SANITIZER
-static_assert(std::is_trivially_destructible<SpinLock>(), "");
+static_assert(std::is_trivially_destructible<SpinLock>());
 #endif
 
 TEST(SpinLock, StackNonCooperativeDisablesScheduling) {
diff --git a/absl/cleanup/cleanup_test.cc b/absl/cleanup/cleanup_test.cc
index 0d407b2..a413b7e 100644
--- a/absl/cleanup/cleanup_test.cc
+++ b/absl/cleanup/cleanup_test.cc
@@ -97,22 +97,19 @@
     auto cleanup = absl::MakeCleanup(std::move(callback));
 
     static_assert(
-        IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(),
-        "");
+        IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>());
   }
 
   {
     auto cleanup = absl::MakeCleanup(&FnPtrFunction);
 
-    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
-                  "");
+    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
   }
 
   {
     auto cleanup = absl::MakeCleanup(FnPtrFunction);
 
-    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
-                  "");
+    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
   }
 }
 
@@ -122,22 +119,19 @@
     absl::Cleanup cleanup = std::move(callback);
 
     static_assert(
-        IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(),
-        "");
+        IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>());
   }
 
   {
     absl::Cleanup cleanup = &FnPtrFunction;
 
-    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
-                  "");
+    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
   }
 
   {
     absl::Cleanup cleanup = FnPtrFunction;
 
-    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
-                  "");
+    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
   }
 }
 
@@ -148,7 +142,7 @@
     absl::Cleanup deduction_cleanup = callback;
 
     static_assert(
-        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
   }
 
   {
@@ -157,7 +151,7 @@
     absl::Cleanup deduction_cleanup = FunctorClassFactory::AsCallback([] {});
 
     static_assert(
-        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
   }
 
   {
@@ -166,7 +160,7 @@
     absl::Cleanup deduction_cleanup = StdFunctionFactory::AsCallback([] {});
 
     static_assert(
-        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
   }
 
   {
@@ -174,7 +168,7 @@
     absl::Cleanup deduction_cleanup = &FnPtrFunction;
 
     static_assert(
-        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
   }
 
   {
@@ -182,7 +176,7 @@
     absl::Cleanup deduction_cleanup = FnPtrFunction;
 
     static_assert(
-        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
   }
 }
 
diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h
index aaef5bb..257a624 100644
--- a/absl/container/btree_map.h
+++ b/absl/container/btree_map.h
@@ -371,11 +371,6 @@
   //   does not contain an element with a matching key, this function returns an
   //   empty node handle.
   //
-  // NOTE: when compiled in an earlier version of C++ than C++17,
-  // `node_type::key()` returns a const reference to the key instead of a
-  // mutable reference. We cannot safely return a mutable reference without
-  // std::launder (which is not available before C++17).
-  //
   // NOTE: In this context, `node_type` refers to the C++17 concept of a
   // move-only type that owns and provides access to the elements in associative
   // containers (https://en.cppreference.com/w/cpp/container/node_handle).
@@ -737,11 +732,6 @@
   //   does not contain an element with a matching key, this function returns an
   //   empty node handle.
   //
-  // NOTE: when compiled in an earlier version of C++ than C++17,
-  // `node_type::key()` returns a const reference to the key instead of a
-  // mutable reference. We cannot safely return a mutable reference without
-  // std::launder (which is not available before C++17).
-  //
   // NOTE: In this context, `node_type` refers to the C++17 concept of a
   // move-only type that owns and provides access to the elements in associative
   // containers (https://en.cppreference.com/w/cpp/container/node_handle).
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc
index b2e1f4c..5b76c34 100644
--- a/absl/container/btree_test.cc
+++ b/absl/container/btree_test.cc
@@ -3530,7 +3530,7 @@
   // This breaks if we try to do layout_type::Pointer<slot_type> because
   // slot_type is the same as field_type.
   using set_type = absl::btree_set<uint8_t>;
-  static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), "");
+  static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>());
   TestBasicFunctionality(set_type());
 }
 
diff --git a/absl/container/chunked_queue.h b/absl/container/chunked_queue.h
index 0e686ca..8ada208 100644
--- a/absl/container/chunked_queue.h
+++ b/absl/container/chunked_queue.h
@@ -573,12 +573,6 @@
 };
 
 template <typename T, size_t BLo, size_t BHi, typename Allocator>
-constexpr size_t chunked_queue<T, BLo, BHi, Allocator>::kBlockSizeMin;
-
-template <typename T, size_t BLo, size_t BHi, typename Allocator>
-constexpr size_t chunked_queue<T, BLo, BHi, Allocator>::kBlockSizeMax;
-
-template <typename T, size_t BLo, size_t BHi, typename Allocator>
 inline void swap(chunked_queue<T, BLo, BHi, Allocator>& a,
                  chunked_queue<T, BLo, BHi, Allocator>& b) noexcept {
   a.swap(b);
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index 48ac57f..713c685 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -430,8 +430,8 @@
     return std::addressof(ptr->array);
   }
 
-  static_assert(sizeof(StorageElement) == sizeof(value_type), "");
-  static_assert(alignof(StorageElement) == alignof(value_type), "");
+  static_assert(sizeof(StorageElement) == sizeof(value_type));
+  static_assert(alignof(StorageElement) == alignof(value_type));
 
   class NonEmptyInlinedStorage {
    public:
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h
index f8c3ba7..b434a47 100644
--- a/absl/container/flat_hash_map.h
+++ b/absl/container/flat_hash_map.h
@@ -439,11 +439,6 @@
   //   key value and returns a node handle owning that extracted data. If the
   //   `flat_hash_map` does not contain an element with a matching key, this
   //   function returns an empty node handle.
-  //
-  // NOTE: when compiled in an earlier version of C++ than C++17,
-  // `node_type::key()` returns a const reference to the key instead of a
-  // mutable reference. We cannot safely return a mutable reference without
-  // std::launder (which is not available before C++17).
   using Base::extract;
 
   // flat_hash_map::merge()
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc
index effbae3..213cb70 100644
--- a/absl/container/flat_hash_map_test.cc
+++ b/absl/container/flat_hash_map_test.cc
@@ -66,7 +66,7 @@
 using Map = flat_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual,
                           Alloc<std::pair<const K, V>>>;
 
-static_assert(!std::is_standard_layout<NonStandardLayout>(), "");
+static_assert(!std::is_standard_layout<NonStandardLayout>());
 
 using MapTypes =
     ::testing::Types<Map<int, int>, Map<std::string, int>,
@@ -92,7 +92,7 @@
     bool operator==(const Int& other) const { return value == other.value; }
     size_t value;
   };
-  static_assert(std::is_standard_layout<Int>(), "");
+  static_assert(std::is_standard_layout<Int>());
 
   struct Hash {
     size_t operator()(const Int& obj) const { return obj.value; }
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 2694a5d..8dfbf03 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -893,8 +893,8 @@
     // Assumption check: we shouldn't be told to use memcpy to implement move
     // assignment unless we have trivially destructible elements and an
     // allocator that does nothing fancy.
-    static_assert(std::is_trivially_destructible_v<value_type>, "");
-    static_assert(std::is_same_v<A, std::allocator<value_type>>, "");
+    static_assert(std::is_trivially_destructible_v<value_type>);
+    static_assert(std::is_same_v<A, std::allocator<value_type>>);
 
     // Throw away our existing heap allocation, if any. There is no need to
     // destroy the existing elements one by one because we know they are
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h
index 5f5b66b..55ff457 100644
--- a/absl/container/internal/btree.h
+++ b/absl/container/internal/btree.h
@@ -97,7 +97,8 @@
 #endif
 
 template <typename Compare, typename T, typename U>
-using compare_result_t = absl::result_of_t<const Compare(const T &, const U &)>;
+using compare_result_t =
+    std::invoke_result_t<const Compare, const T &, const U &>;
 
 // A helper class that indicates if the Compare parameter is a key-compare-to
 // comparator.
diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h
index 429bf31..b2839e6 100644
--- a/absl/container/internal/common.h
+++ b/absl/container/internal/common.h
@@ -194,8 +194,6 @@
 
   constexpr node_handle() {}
 
-  // When C++17 is available, we can use std::launder to provide mutable
-  // access to the key. Otherwise, we provide const access.
   auto key() const
       -> decltype(PolicyTraits::mutable_key(std::declval<slot_type*>())) {
     return PolicyTraits::mutable_key(this->slot());
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index 81346f9..1d361f5 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -60,7 +60,7 @@
 // returns insufficiently alignment pointer, that's what you are going to get.
 template <size_t Alignment, class Alloc>
 void* Allocate(Alloc* alloc, size_t n) {
-  static_assert(Alignment > 0, "");
+  static_assert(Alignment > 0);
   assert(n && "n must be positive");
   using M = AlignedType<Alignment>;
   using A = typename std::allocator_traits<Alloc>::template rebind_alloc<M>;
@@ -91,7 +91,7 @@
 // Allocate<Alignment>(alloc, n).
 template <size_t Alignment, class Alloc>
 void Deallocate(Alloc* alloc, void* p, size_t n) {
-  static_assert(Alignment > 0, "");
+  static_assert(Alignment > 0);
   assert(n && "n must be positive");
   using M = AlignedType<Alignment>;
   using A = typename std::allocator_traits<Alloc>::template rebind_alloc<M>;
diff --git a/absl/container/internal/hashtable_control_bytes.h b/absl/container/internal/hashtable_control_bytes.h
index fd4dea4..b0faec3 100644
--- a/absl/container/internal/hashtable_control_bytes.h
+++ b/absl/container/internal/hashtable_control_bytes.h
@@ -125,9 +125,9 @@
           bool NullifyBitsOnIteration = false>
 class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> {
   using Base = NonIterableBitMask<T, SignificantBits, Shift>;
-  static_assert(std::is_unsigned_v<T>, "");
-  static_assert(Shift == 0 || Shift == 3, "");
-  static_assert(!NullifyBitsOnIteration || Shift == 3, "");
+  static_assert(std::is_unsigned_v<T>);
+  static_assert(Shift == 0 || Shift == 3);
+  static_assert(!NullifyBitsOnIteration || Shift == 3);
 
  public:
   explicit BitMask(T mask) : Base(mask) {
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h
index e6491ba..5b9763e 100644
--- a/absl/container/internal/inlined_vector.h
+++ b/absl/container/internal/inlined_vector.h
@@ -76,7 +76,7 @@
 template <typename A>
 using IsMoveAssignOk = std::is_move_assignable<ValueType<A>>;
 template <typename A>
-using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>;
+using IsSwapOk = std::is_swappable<ValueType<A>>;
 
 template <typename A, bool IsTriviallyDestructible =
                           std::is_trivially_destructible_v<ValueType<A>> &&
diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h
index fac7d81..a4cfe59 100644
--- a/absl/container/internal/layout.h
+++ b/absl/container/internal/layout.h
@@ -317,11 +317,10 @@
 // Can `T` be a template argument of `Layout`?
 template <class T>
 using IsLegalElementType =
-    std::integral_constant<bool,
-                           !std::is_reference_v<T> && !std::is_volatile_v<T> &&
-                               !std::is_reference_v<typename Type<T>::type> &&
-                               !std::is_volatile_v<typename Type<T>::type> &&
-                               adl_barrier::IsPow2(AlignOf<T>::value)>;
+    std::bool_constant<!std::is_reference_v<T> && !std::is_volatile_v<T> &&
+                       !std::is_reference_v<typename Type<T>::type> &&
+                       !std::is_volatile_v<typename Type<T>::type> &&
+                       adl_barrier::IsPow2(AlignOf<T>::value)>;
 
 template <class Elements, class StaticSizeSeq, class RuntimeSizeSeq,
           class SizeSeq, class OffsetSeq>
@@ -739,8 +738,7 @@
   // Requires: all arguments are convertible to `size_t`.
   template <class... Sizes>
   static constexpr PartialType<sizeof...(Sizes)> Partial(Sizes&&... sizes) {
-    static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts),
-                  "");
+    static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts));
     return PartialType<sizeof...(Sizes)>(
         static_cast<size_t>(std::forward<Sizes>(sizes))...);
   }
diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc
index e99c56a..d2d1196 100644
--- a/absl/container/internal/layout_test.cc
+++ b/absl/container/internal/layout_test.cc
@@ -50,7 +50,7 @@
 
 template <class Expected, class Actual>
 Expected Type(Actual val) {
-  static_assert(std::is_same<Expected, Actual>(), "");
+  static_assert(std::is_same<Expected, Actual>());
   return val;
 }
 
@@ -73,20 +73,20 @@
 };
 
 // Properties of types that this test relies on.
-static_assert(sizeof(int8_t) == 1, "");
-static_assert(alignof(int8_t) == 1, "");
-static_assert(sizeof(int16_t) == 2, "");
-static_assert(alignof(int16_t) == 2, "");
-static_assert(sizeof(int32_t) == 4, "");
-static_assert(alignof(int32_t) == 4, "");
-static_assert(sizeof(Int64) == 8, "");
-static_assert(alignof(Int64) == 8, "");
-static_assert(sizeof(Int128) == 16, "");
-static_assert(alignof(Int128) == 8, "");
+static_assert(sizeof(int8_t) == 1);
+static_assert(alignof(int8_t) == 1);
+static_assert(sizeof(int16_t) == 2);
+static_assert(alignof(int16_t) == 2);
+static_assert(sizeof(int32_t) == 4);
+static_assert(alignof(int32_t) == 4);
+static_assert(sizeof(Int64) == 8);
+static_assert(alignof(Int64) == 8);
+static_assert(sizeof(Int128) == 16);
+static_assert(alignof(Int128) == 8);
 
 template <class Expected, class Actual>
 void SameType() {
-  static_assert(std::is_same<Expected, Actual>(), "");
+  static_assert(std::is_same<Expected, Actual>());
 }
 
 TEST(Layout, ElementType) {
@@ -1435,7 +1435,7 @@
   template <typename Tuple>
   bool MatchAndExplain(const Tuple& p,
                        testing::MatchResultListener* /* listener */) const {
-    static_assert(std::tuple_size<Tuple>::value == sizeof...(M), "");
+    static_assert(std::tuple_size<Tuple>::value == sizeof...(M));
     return MatchAndExplainImpl(
         p, std::make_index_sequence<std::tuple_size<Tuple>::value>{});
   }
@@ -1597,52 +1597,50 @@
 }
 
 TEST(Layout, Alignment) {
-  static_assert(Layout<int8_t>::Alignment() == 1, "");
-  static_assert(Layout<int32_t>::Alignment() == 4, "");
-  static_assert(Layout<Int64>::Alignment() == 8, "");
-  static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, "");
-  static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, "");
-  static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, "");
-  static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, "");
-  static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, "");
-  static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, "");
-  static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
-  static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
-  static_assert(
-      Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, "");
-  static_assert(
-      Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, "");
+  static_assert(Layout<int8_t>::Alignment() == 1);
+  static_assert(Layout<int32_t>::Alignment() == 4);
+  static_assert(Layout<Int64>::Alignment() == 8);
+  static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64);
+  static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8);
+  static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8);
+  static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8);
+  static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8);
+  static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8);
+  static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8);
+  static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8);
+  static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() ==
+                64);
+  static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() ==
+                64);
 }
 
 TEST(Layout, StaticAlignment) {
-  static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1, "");
-  static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1, "");
-  static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1, "");
-  static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4, "");
-  static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4, "");
-  static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4, "");
+  static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1);
+  static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1);
+  static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1);
+  static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4);
+  static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4);
+  static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4);
+  static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() ==
+                64);
+  static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() ==
+                64);
+  static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() ==
+                64);
   static_assert(
-      Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, "");
-  static_assert(
-      Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() == 64, "");
-  static_assert(
-      Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, "");
-  static_assert(
-      Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8, "");
+      Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8);
   static_assert(
       Layout<int32_t, Int64, int8_t>::WithStaticSizes<0, 0, 0>::Alignment() ==
-          8,
-      "");
+      8);
   static_assert(
       Layout<int32_t, Int64, int8_t>::WithStaticSizes<1, 1, 1>::Alignment() ==
-          8,
-      "");
+      8);
 }
 
 TEST(Layout, ConstexprPartial) {
   constexpr size_t M = alignof(max_align_t);
   constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
-  static_assert(x.Partial(1).template Offset<1>() == 2 * M, "");
+  static_assert(x.Partial(1).template Offset<1>() == 2 * M);
 }
 
 TEST(Layout, StaticConstexpr) {
@@ -1650,7 +1648,7 @@
   using L = Layout<unsigned char, Aligned<unsigned char, 2 * M>>;
   using SL = L::WithStaticSizes<1, 3>;
   constexpr SL x;
-  static_assert(x.Offset<1>() == 2 * M, "");
+  static_assert(x.Offset<1>() == 2 * M);
 }
 
 // [from, to)
diff --git a/absl/container/internal/node_slot_policy.h b/absl/container/internal/node_slot_policy.h
index 7213dda..4a7dca2 100644
--- a/absl/container/internal/node_slot_policy.h
+++ b/absl/container/internal/node_slot_policy.h
@@ -47,7 +47,7 @@
 
 template <class Reference, class Policy>
 struct node_slot_policy {
-  static_assert(std::is_lvalue_reference_v<Reference>, "");
+  static_assert(std::is_lvalue_reference_v<Reference>);
 
   using slot_type = std::remove_cv_t<std::remove_reference_t<Reference>>*;
 
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h
index 04e9e61..8301b50 100644
--- a/absl/container/internal/raw_hash_map.h
+++ b/absl/container/internal/raw_hash_map.h
@@ -95,11 +95,11 @@
   using key_type = typename Policy::key_type;
   using mapped_type = typename Policy::mapped_type;
 
-  static_assert(!std::is_reference_v<key_type>, "");
+  static_assert(!std::is_reference_v<key_type>);
 
   // TODO(b/187807849): Evaluate whether to support reference mapped_type and
   // remove this assertion if/when it is supported.
-  static_assert(!std::is_reference_v<mapped_type>, "");
+  static_assert(!std::is_reference_v<mapped_type>);
 
   using iterator = typename raw_hash_map::raw_hash_set::iterator;
   using const_iterator = typename raw_hash_map::raw_hash_set::const_iterator;
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
index d37c781..3f9263c 100644
--- a/absl/container/internal/raw_hash_set.cc
+++ b/absl/container/internal/raw_hash_set.cc
@@ -141,9 +141,8 @@
 
 // Must be defined out-of-line to avoid MSVC error C2482 on some platforms,
 // which is caused by non-constexpr initialization.
-uint16_t NextHashTableSeed() {
-  static_assert(PerTableSeed::kBitCount <= 16);
-  return static_cast<uint16_t>(RandomSeed());
+uint8_t NextHashTableSeed() {
+  return static_cast<uint8_t>(RandomSeed());
 }
 
 GenerationType* EmptyGeneration() {
@@ -943,6 +942,7 @@
         destroy_slot(&c, SingleSlotAddress<kSooEnabled>(c));
       }
       DecrementSmallSize<kSooEnabled>(c);
+      c.infoz().RecordStorageChanged(0, cap);
     }
   } else {
     if (destroy_slot != nullptr) {
@@ -2289,7 +2289,10 @@
   const size_t slot_size = policy.slot_size;
   const bool soo_enabled = policy.soo_enabled;
   if (size == 1) {
-    if (!soo_enabled) ReserveTableToFitNewSize(common, policy, 1);
+    if (!soo_enabled) {
+      ReserveEmptyNonAllocatedTableToFitNewSize(common, policy, 1);
+      common.infoz().RecordStorageChanged(1, 1);
+    }
     IncrementSmallSize(common, policy);
     const size_t other_capacity = other.capacity();
     const void* other_slot =
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 5a4fce8..0531300 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -568,7 +568,9 @@
   // We use these sentinel capacity values in debug mode to indicate different
   // classes of bugs.
   enum InvalidCapacity : IntType {
-    kAboveMaxValidCapacity = (std::numeric_limits<IntType>::max)() - 100,
+    kAboveMaxValidCapacity = StorageMode == kCapacityByValue
+                                 ? (std::numeric_limits<IntType>::max)() - 100
+                                 : 64 - 10,
     kReentrance,
     kDestroyed,
 
@@ -590,39 +592,24 @@
 class HashtableInlineDataImpl;
 
 // Returns next per-table seed.
-uint16_t NextHashTableSeed();
+uint8_t NextHashTableSeed();
 
 // Per table hash salt. This gets mixed into H1 to randomize iteration order
 // per-table.
 // The seed is needed to ensure non-determinism of iteration order.
-template <typename StorageType>
-class PerTableSeedImpl {
+class PerTableSeed {
  public:
-  using IntType = StorageType;
-
-  // The number of bits in the seed.
-  // It is big enough to ensure non-determinism of iteration order.
-  // We store the seed inside a uint64_t together with size and other metadata.
-  // Using 8 or 16 bits allows us to save one `and` instruction in H1 (we use
-  // zero-extended move instead of mov+and). When absl::Hash is inlined, it can
-  // also have lower latency knowing that the high bits of the seed are zero.
-  static constexpr size_t kBitCount = sizeof(IntType) * 8;
-
-  // We need to use a constant seed when the table is sampled so that sampled
-  // hashes use the same seed and can e.g. identify stuck bits accurately.
-  static constexpr IntType kSampledSeed = static_cast<IntType>(~IntType{0});
-
   // Returns the seed for the table.
   size_t seed() const { return seed_; }
 
  private:
-  template <HashtableCapacityStorageMode StorageMode>
+  template <HashtableCapacityStorageMode StorageModeOfData>
   friend class HashtableInlineDataImpl;
 
-  explicit PerTableSeedImpl(uint64_t seed)
-      : seed_(static_cast<IntType>(seed)) {}
+  explicit PerTableSeed(uint64_t seed)
+      : seed_(static_cast<uint16_t>(seed)) {}
 
-  const IntType seed_;
+  const uint16_t seed_;
 };
 
 // Represents blocked elements info: log2_period and tail_blocked.
@@ -672,18 +659,25 @@
 //    bit of the seed is repurposed to track if sampling has been tried).
 template <HashtableCapacityStorageMode StorageMode>
 class HashtableInlineDataImpl {
+  // The number of bits in the seed. It is big enough to ensure
+  // non-determinism of iteration order. We store the seed inside a uint64_t
+  // together with size and other metadata. When absl::Hash is inlined, it can
+  // have lower latency knowing that the high bits of the seed are zero.
+  static constexpr size_t kSeedBitCount = 5;
+
  public:
   static constexpr HashtableCapacityStorageMode kStorageMode = StorageMode;
-  using PerTableSeed = PerTableSeedImpl<
-      std::conditional_t<StorageMode == kCapacityByValue, uint16_t, uint8_t>>;
   using HashtableCapacity = HashtableCapacityImpl<StorageMode>;
   static constexpr size_t kBlockedElementBitCount = 3;
   static constexpr size_t kMaxBlockedElementCount =
       (uint64_t{1} << kBlockedElementBitCount) - 1;
+  static constexpr size_t kCapacityBitCount =
+      StorageMode == kCapacityByValue ? sizeof(HashtableCapacity) * 8 : 6;
+  static constexpr size_t kCapacityBitStoredInDataCount =
+      StorageMode == kCapacityByValue ? 0 : kCapacityBitCount;
   static constexpr size_t kSizeBitCount =
-      64 -
-      (kBlockedElementBitCount + PerTableSeed::kBitCount + /*has_infoz*/ 1 +
-       (StorageMode == kCapacityByValue ? 0 : sizeof(HashtableCapacity) * 8));
+      64 - (kBlockedElementBitCount + kSeedBitCount +
+            /*has_infoz*/ 1 + kCapacityBitStoredInDataCount);
 
   explicit HashtableInlineDataImpl(uninitialized_tag_t) {}
   explicit HashtableInlineDataImpl(HashtableCapacity capacity,
@@ -727,18 +721,18 @@
         (data_ & kMetadataMask) | (static_cast<uint64_t>(size) << kSizeShift);
   }
 
-  PerTableSeed seed() const { return PerTableSeed(data_ & kSeedMask); }
-
-  void generate_new_seed() {
-    set_seed(static_cast<typename PerTableSeed::IntType>(NextHashTableSeed()));
+  PerTableSeed seed() const {
+    return PerTableSeed(ToPublicSeed(data_ & kSeedMask));
   }
 
+  void generate_new_seed() { set_seed(NextHashTableSeed()); }
+
   // We need to use a constant seed when the table is sampled so that sampled
   // hashes use the same seed and can e.g. identify stuck bits accurately.
-  void set_sampled_seed() { set_seed(PerTableSeed::kSampledSeed); }
+  void set_sampled_seed() { set_seed(kSampledSeed); }
 
   bool is_sampled_seed() const {
-    return seed().seed() == PerTableSeed::kSampledSeed;
+    return seed().seed() == ToPublicSeed(kSampledSeed);
   }
 
   // Returns true if the table has infoz.
@@ -767,34 +761,46 @@
   void set_no_seed_for_testing() { data_ &= ~kSeedMask; }
 
  private:
-  // Bit layout of `data_` from MSB to LSB:
-  // (44 bits)      : size
+  // Bit layout of `data_` and `capacity_internal_` from MSB to LSB:
+  // (55/49 bits)   : size
   // (3 bits)       : blocked_element_count
   // (1 bit)        : has_infoz
-  // (16 or 8 bits) : seed
+  // (5 bits)       : seed
+  // (6 bits)       : capacity (only for kCapacityByLog)
   // We don't split these components of `data_` into separate bit field elements
   // because we get worse generated code that way.
+
   static constexpr size_t kDataBitCount =
-      PerTableSeed::kBitCount + 1 + kSizeBitCount + kBlockedElementBitCount;
+      kSeedBitCount + 1 + kSizeBitCount + kBlockedElementBitCount;
   static constexpr size_t kSizeShift = kDataBitCount - kSizeBitCount;
   static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift;
   static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
-  static constexpr uint64_t kSeedMask =
-      (uint64_t{1} << PerTableSeed::kBitCount) - 1;
+  static constexpr uint64_t kSeedMask = (uint64_t{1} << kSeedBitCount) - 1;
   // The next bit after the seed.
   static constexpr uint64_t kHasInfozMask = kSeedMask + 1;
-  static constexpr uint64_t kBlockedElementsShift = PerTableSeed::kBitCount + 1;
+  static constexpr uint64_t kBlockedElementsShift = kSeedBitCount + 1;
   static constexpr uint64_t kBlockedElementMask = kMaxBlockedElementCount
                                                   << kBlockedElementsShift;
   // For SOO tables, the seed is unused, and bit 0 is repurposed to track
   // whether the table has already queried should_sample_soo().
   static constexpr uint64_t kSooHasTriedSamplingMask = 1;
 
-  void set_seed(typename PerTableSeed::IntType seed) {
-    data_ = (data_ & ~kSeedMask) | seed;
+  // We need to use a constant seed when the table is sampled so that sampled
+  // hashes use the same seed and can e.g. identify stuck bits accurately.
+  static constexpr uint8_t kSampledSeed = (1 << kSeedBitCount) - 1;
+
+  static constexpr uint64_t ToPublicSeed(uint64_t seed) {
+    // In kCapacityByLog mode, we shift public seed to the left to keep bits of
+    // the seed in the original place. It allows us to use single instruction to
+    // access the seed (e.g., `andl $0x7c0, %r8d`).
+    return seed << kCapacityBitStoredInDataCount;
   }
 
-  uint64_t capacity_internal_ : sizeof(HashtableCapacity) * 8;
+  void set_seed(uint8_t seed) {
+    data_ = (data_ & ~kSeedMask) | (seed & kSeedMask);
+  }
+
+  uint64_t capacity_internal_ : kCapacityBitCount;
   uint64_t data_ : kDataBitCount;
 };
 
@@ -814,7 +820,6 @@
 #else
 using HashtableInlineData = HashtableInlineDataImpl<kCapacityByValue>;
 #endif  // ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE
-using PerTableSeed = HashtableInlineData::PerTableSeed;
 using HashtableCapacity = HashtableInlineData::HashtableCapacity;
 
 // For large tables, we limit the number of blocked elements to maintain O(1)
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 469341e..c52c692 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -1352,8 +1352,8 @@
                ChangingSizeAndTrackingTypeAlloc<int64_t>>;
 
 TEST(Table, EmptyFunctorOptimization) {
-  static_assert(std::is_empty_v<std::equal_to<absl::string_view>>, "");
-  static_assert(std::is_empty_v<std::allocator<int>>, "");
+  static_assert(std::is_empty_v<std::equal_to<absl::string_view>>);
+  static_assert(std::is_empty_v<std::allocator<int>>);
 
   struct MockTableByValue {
     size_t capacity;
@@ -1545,13 +1545,12 @@
   for (size_t capacity = 31; capacity < 256;
        capacity = NextCapacity(capacity)) {
     SCOPED_TRACE(absl::StrCat("capacity: ", capacity));
-    // Number of elements we keep empty in order to force a rehash without
+    // Number of elements we reserve in order to force a rehash without
     // growth. RehashOrGrowToNextCapacityAndPrepareInsert grow if number of full
-    // slots is greater than 25/32 of capacity, so we leave 7/32 + 5 empty to
-    // have extra margin.
-    size_t empty_till_full = (capacity + 1) / 32 * 7 + 5;
+    // slots is greater than 25/32 of capacity. We reserve slightly less than
+    // 25/32 of capacity to have extra space for tombstones.
     int64_t reserve_size =
-        static_cast<int64_t>(CapacityToGrowth(capacity) - empty_till_full);
+        static_cast<int64_t>((capacity - 5) * 25 / 32 - 2);
 
     BadTwoValuesHashTable t(
         0,
@@ -1560,9 +1559,8 @@
         // will be placed at the beginning of the table.
         BadTwoValuesHash(static_cast<size_t>(reserve_size)));
     // Remove seed to make table layout deterministic.
-    RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing();
-
     t.reserve(static_cast<size_t>(reserve_size));
+    RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing();
     for (int64_t i = 1; i <= reserve_size; ++i) {
       ASSERT_TRUE(t.insert(i * kCoef).second);
     }
@@ -1632,10 +1630,9 @@
   BadTwoValuesHashTable t(0,
                           // Negative number goes to the end of the table.
                           BadTwoValuesHash(kReserveSize + 2));
+  t.reserve(kReserveSize);
   // Remove seed to make table layout deterministic.
   RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing();
-
-  t.reserve(kReserveSize);
   for (int64_t i = 0; i < static_cast<int64_t>(Group::kWidth); ++i) {
     ASSERT_TRUE(t.insert(i * kCoef).second);
   }
@@ -4109,6 +4106,22 @@
   }
 }
 
+TEST(RawHashSamplerTest, NonSooTableRepeatedInsertClearCountSizeRight) {
+  ASSERT_EQ(NonSooIntTable().capacity(), 0);
+  std::vector<const HashtablezInfo*> infos =
+      SampleNonSooMutation([](NonSooIntTable& t) {
+        for (int i = 0; i < 10; ++i) {
+          t.insert(1);
+          t.clear();
+        }
+      });
+  for (const HashtablezInfo* info : infos) {
+    EXPECT_EQ(info->soo_capacity, 0);
+    ASSERT_EQ(info->capacity, 1);
+    ASSERT_EQ(info->size, 0);
+  }
+}
+
 // Verifies that copy-constructing or copy-assigning an SOO table does not
 // incorrectly trigger new sampling evaluations.
 TEST(RawHashSamplerTest, SooTableCopyDoesNotOversample) {
@@ -4217,6 +4230,22 @@
   }
 }
 
+TEST(RawHashSamplerTest, NonSooTableSampleOnCopy) {
+  NonSooIntTable t_orig;
+  t_orig.insert(1);
+
+  std::vector<const HashtablezInfo*> infos =
+      SampleNonSooMutation([&t_orig](NonSooIntTable& t) { t = t_orig; });
+
+  for (const HashtablezInfo* info : infos) {
+    ASSERT_EQ(info->inline_element_size,
+              sizeof(typename NonSooIntTable::value_type));
+    ASSERT_EQ(info->soo_capacity, 0);
+    ASSERT_EQ(info->capacity, 1);
+    ASSERT_EQ(info->size, 1);
+  }
+}
+
 // This tests that rehash(0) on a sampled table with size that fits in SOO
 // doesn't incorrectly result in losing sampling.
 TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h
index 2c9f57f..932c320 100644
--- a/absl/container/internal/unordered_set_lookup_test.h
+++ b/absl/container/internal/unordered_set_lookup_test.h
@@ -52,11 +52,9 @@
   for (const auto& v : values) {
     typename TypeParam::iterator it = m.find(v);
     static_assert(
-        std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>,
-        "");
+        std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>);
     static_assert(std::is_same<const typename TypeParam::value_type*,
-                               decltype(it.operator->())>::value,
-                  "");
+                               decltype(it.operator->())>::value);
     EXPECT_TRUE(m.end() != it) << ::testing::PrintToString(v);
     EXPECT_EQ(v, *it) << ::testing::PrintToString(v);
   }
diff --git a/absl/container/linked_hash_map_test.cc b/absl/container/linked_hash_map_test.cc
index e8df807..8b95c12 100644
--- a/absl/container/linked_hash_map_test.cc
+++ b/absl/container/linked_hash_map_test.cc
@@ -53,7 +53,7 @@
 using Map = linked_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual,
                             Alloc<std::pair<const K, V>>>;
 
-static_assert(!std::is_standard_layout<NonStandardLayout>(), "");
+static_assert(!std::is_standard_layout<NonStandardLayout>());
 
 using MapTypes =
     ::testing::Types<Map<int, int>, Map<std::string, int>,
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h
index d58feed..bd2f426 100644
--- a/absl/container/node_hash_map.h
+++ b/absl/container/node_hash_map.h
@@ -428,10 +428,6 @@
   //   `node_hash_map` does not contain an element with a matching key, this
   //   function returns an empty node handle.
   //
-  // NOTE: when compiled in an earlier version of C++ than C++17,
-  // `node_type::key()` returns a const reference to the key instead of a
-  // mutable reference. We cannot safely return a mutable reference without
-  // std::launder (which is not available before C++17).
   using Base::extract;
 
   // node_hash_map::merge()
diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc
index 107b329..476b12f 100644
--- a/absl/container/node_hash_map_test.cc
+++ b/absl/container/node_hash_map_test.cc
@@ -196,7 +196,7 @@
 
   // NonMovableKey is neither copyable nor movable. We should still be able to
   // move nodes around.
-  static_assert(!std::is_move_constructible_v<NonMovableKey>, "");
+  static_assert(!std::is_move_constructible_v<NonMovableKey>);
   set1.merge(set2);
 
   EXPECT_THAT(set1,
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index 46cb97f..745f773 100644
--- a/absl/debugging/failure_signal_handler.cc
+++ b/absl/debugging/failure_signal_handler.cc
@@ -71,7 +71,7 @@
 // Checks whether pthread_cpu_number_np is available.
 #ifdef ABSL_HAVE_PTHREAD_CPU_NUMBER_NP
 #error ABSL_HAVE_PTHREAD_CPU_NUMBER_NP cannot be directly set
-#elif defined(__APPLE__) && defined(__has_include) &&              \
+#elif defined(__APPLE__) &&                                        \
     ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) &&    \
       __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000) ||  \
      (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) &&   \
diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h
index c82d4a3..1ce2ad6 100644
--- a/absl/debugging/internal/stacktrace_config.h
+++ b/absl/debugging/internal/stacktrace_config.h
@@ -18,6 +18,9 @@
  * This header is "private" to stacktrace.cc.
  * DO NOT include it into any other files.
 */
+
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
 #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
 #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
 
@@ -59,7 +62,7 @@
 #define ABSL_STACKTRACE_INL_HEADER \
   "absl/debugging/internal/stacktrace_libunwind-inl.inc"
 #define STACKTRACE_USES_LIBUNWIND 1
-#elif defined(NO_FRAME_POINTER) && defined(__has_include)
+#elif defined(NO_FRAME_POINTER)
 #if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)
 // Note: When using glibc this may require -funwind-tables to function properly.
 #define ABSL_STACKTRACE_INL_HEADER \
@@ -77,13 +80,13 @@
 #elif defined(__riscv)
 #define ABSL_STACKTRACE_INL_HEADER \
   "absl/debugging/internal/stacktrace_riscv-inl.inc"
-#elif defined(__has_include)
+#else
 #if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)
 // Note: When using glibc this may require -funwind-tables to function properly.
 #define ABSL_STACKTRACE_INL_HEADER \
   "absl/debugging/internal/stacktrace_generic-inl.inc"
 #endif  // __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)
-#endif  // defined(__has_include)
+#endif
 
 #endif  // defined(__linux__) && !defined(__ANDROID__)
 
diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc
index f7e2a44..d9dfccb 100644
--- a/absl/debugging/internal/vdso_support.cc
+++ b/absl/debugging/internal/vdso_support.cc
@@ -21,10 +21,6 @@
 
 #ifdef ABSL_HAVE_VDSO_SUPPORT     // defined in vdso_support.h
 
-#if !defined(__has_include)
-#define __has_include(header) 0
-#endif
-
 #include <errno.h>
 #include <fcntl.h>
 #if __has_include(<syscall.h>)
diff --git a/absl/debugging/stacktrace_test.cc b/absl/debugging/stacktrace_test.cc
index 17552b4..0bf94f7 100644
--- a/absl/debugging/stacktrace_test.cc
+++ b/absl/debugging/stacktrace_test.cc
@@ -312,7 +312,8 @@
 const void* g_return_address = nullptr;
 bool g_sigusr2_raised = false;
 
-void SigUsr2Handler(int, siginfo_t*, void* uc) {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS void SigUsr2Handler(int, siginfo_t*,
+                                                       void* uc) {
   absl::base_internal::ErrnoSaver errno_saver;
   // Many platforms don't support this by default.
   bool support_is_expected = false;
@@ -333,18 +334,19 @@
   g_sigusr2_raised = true;
 }
 
-void SigUsr1Handler(int, siginfo_t*, void*) {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS void SigUsr1Handler(int, siginfo_t*, void*) {
   raise(SIGUSR2);
   ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
 }
 
-ABSL_ATTRIBUTE_NOINLINE void RaiseSignal() {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE void RaiseSignal() {
   g_return_address = __builtin_return_address(0);
   raise(SIGUSR1);
   ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
 }
 
-ABSL_ATTRIBUTE_NOINLINE void TestNestedSignal() {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE void
+TestNestedSignal() {
   constexpr size_t kAltstackSize = 1 << 14;
   // Allocate altstack on regular stack to make sure it'll have a higher
   // address than some of the regular stack frames.
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index 1272168..7855a10 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -304,13 +304,11 @@
 
 template <typename T>
 using FlagUseOneWordStorage =
-    std::integral_constant<bool,
-                           std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>;
+    std::bool_constant<std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>;
 
 template <class T>
 using FlagUseSequenceLockStorage =
-    std::integral_constant<bool,
-                           std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>;
+    std::bool_constant<std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>;
 
 enum class FlagValueStorageKind : uint8_t {
   kValueAndInitBit = 0,
diff --git a/absl/flags/internal/sequence_lock_test.cc b/absl/flags/internal/sequence_lock_test.cc
index c3ec372..a244d67 100644
--- a/absl/flags/internal/sequence_lock_test.cc
+++ b/absl/flags/internal/sequence_lock_test.cc
@@ -113,12 +113,12 @@
   return result;
 }
 
-#ifndef ABSL_HAVE_THREAD_SANITIZER
-const int kMaxThreads = absl::base_internal::NumCPUs();
-#else
+#if defined(ABSL_HAVE_THREAD_SANITIZER)
 // With TSAN, a lot of threads contending for atomic access on the sequence
 // lock make this test run too slowly.
 const int kMaxThreads = std::min(absl::base_internal::NumCPUs(), 4);
+#else
+const int kMaxThreads = absl::base_internal::NumCPUs();
 #endif
 
 // Return all of the interesting buffer sizes worth testing:
diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc
index fb64a65..e92ff96 100644
--- a/absl/flags/reflection.cc
+++ b/absl/flags/reflection.cc
@@ -294,8 +294,8 @@
 }  // namespace
 
 void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf) {
-  static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, "");
-  static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, "");
+  static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize);
+  static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment);
   auto* flag = ::new (buf) flags_internal::RetiredFlagObj(name, type_id);
   FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr);
 }
diff --git a/absl/functional/any_invocable_test.h b/absl/functional/any_invocable_test.h
index 643f14f..d667fa4 100644
--- a/absl/functional/any_invocable_test.h
+++ b/absl/functional/any_invocable_test.h
@@ -59,15 +59,14 @@
 // This will cause a recursive trait instantiation if the SFINAE checks are
 // not ordered correctly for constructibility.
 static_assert(std::is_constructible_v<Wrapper<absl::AnyInvocable<void()>>,
-                                      Wrapper<absl::AnyInvocable<void()>>>,
-              "");
+                                      Wrapper<absl::AnyInvocable<void()>>>);
 
 // A metafunction that takes the cv and l-value reference qualifiers that were
 // associated with a function type (here passed via qualifiers of an object
 // type), and .
 template <class Qualifiers, class This>
 struct QualifiersForThisImpl {
-  static_assert(std::is_object_v<This>, "");
+  static_assert(std::is_object_v<This>);
   using type =
       std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&;
 };
@@ -78,7 +77,7 @@
 
 template <class Qualifiers, class This>
 struct QualifiersForThisImpl<Qualifiers&&, This> {
-  static_assert(std::is_object_v<This>, "");
+  static_assert(std::is_object_v<This>);
   using type =
       std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&&;
 };
@@ -1011,7 +1010,7 @@
     EXPECT_FALSE(static_cast<bool>(other));
 
     EXPECT_TRUE(
-        absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+        std::is_nothrow_swappable_v<AnyInvType>);
   }
 
   // Member swap
@@ -1046,7 +1045,7 @@
     EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
 
     EXPECT_TRUE(
-        absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+        std::is_nothrow_swappable_v<AnyInvType>);
   }
 
   // Member swap
@@ -1083,7 +1082,7 @@
     EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
 
     EXPECT_TRUE(
-        absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+        std::is_nothrow_swappable_v<AnyInvType>);
   }
 
   // Member swap
@@ -1121,7 +1120,7 @@
     EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
 
     EXPECT_TRUE(
-        absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+        std::is_nothrow_swappable_v<AnyInvType>);
   }
 
   // Member swap
@@ -1280,8 +1279,8 @@
     Result(Result&&) = delete;
   };
 
-  static_assert(!std::is_move_constructible_v<Result>, "");
-  static_assert(!std::is_copy_constructible_v<Result>, "");
+  static_assert(!std::is_move_constructible_v<Result>);
+  static_assert(!std::is_copy_constructible_v<Result>);
 
   // Assumption check: it should nevertheless be possible to use functors that
   // return a Result struct according to the language rules.
@@ -1358,8 +1357,8 @@
     Result(Result&&) = delete;
   };
 
-  static_assert(!std::is_move_constructible_v<Result>, "");
-  static_assert(!std::is_copy_constructible_v<Result>, "");
+  static_assert(!std::is_move_constructible_v<Result>);
+  static_assert(!std::is_copy_constructible_v<Result>);
 
   // Assumption check: it should nevertheless be possible to use functors that
   // return a Result struct according to the language rules.
@@ -1590,9 +1589,8 @@
 
 // Minimal SFINAE testing for platforms where we can't run the tests, but we can
 // build binaries for.
-static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>,
-              "");
-static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>, "");
+static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>);
+static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>);
 
 }  // namespace absl_any_invocable_test
 
diff --git a/absl/functional/bind_back.h b/absl/functional/bind_back.h
index ba31fb4..8d9ff7c 100644
--- a/absl/functional/bind_back.h
+++ b/absl/functional/bind_back.h
@@ -30,11 +30,9 @@
 #ifndef ABSL_FUNCTIONAL_BIND_BACK_H_
 #define ABSL_FUNCTIONAL_BIND_BACK_H_
 
-#ifdef __has_include
 #if __has_include(<version>)
 #include <version>
 #endif
-#endif
 
 #if defined(__cpp_lib_bind_back) && __cpp_lib_bind_back >= 202202L
 #include <functional>  // For std::bind_back.
diff --git a/absl/functional/bind_front.h b/absl/functional/bind_front.h
index 09adc09..4dcee39 100644
--- a/absl/functional/bind_front.h
+++ b/absl/functional/bind_front.h
@@ -30,11 +30,9 @@
 #ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_
 #define ABSL_FUNCTIONAL_BIND_FRONT_H_
 
-#ifdef __has_include
 #if __has_include(<version>)
 #include <version>
 #endif
-#endif
 
 #if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
 #include <functional>  // For std::bind_front.
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h
index 4698442..1ff8bb6 100644
--- a/absl/functional/internal/any_invocable.h
+++ b/absl/functional/internal/any_invocable.h
@@ -63,7 +63,6 @@
 #include <type_traits>
 #include <utility>
 
-#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/macros.h"
 #include "absl/base/nullability.h"
@@ -252,7 +251,7 @@
     case FunctionToCall::relocate_from_to_and_query_rust:
       // NOTE: Requires that the left-hand operand is already empty.
       ::new (static_cast<void*>(&to->storage)) T(std::move(from_object));
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case FunctionToCall::dispose:
       from_object.~T();  // Must not throw. // NOLINT
       return;
diff --git a/absl/hash/hash_benchmark.cc b/absl/hash/hash_benchmark.cc
index 86650b3..a6b0e81 100644
--- a/absl/hash/hash_benchmark.cc
+++ b/absl/hash/hash_benchmark.cc
@@ -196,7 +196,7 @@
   auto t6 = std::tuple_cat(t5, t5);
   // Ideally this would be much larger, but some configurations can't handle
   // making tuples with that many elements. They break inside std::tuple itself.
-  static_assert(std::tuple_size<decltype(t6)>::value == 32, "");
+  static_assert(std::tuple_size<decltype(t6)>::value == 32);
   return t6;
 }
 
@@ -344,7 +344,7 @@
 static char entropy[kEntropySize + 1024];
 ABSL_ATTRIBUTE_UNUSED static const bool kInitialized = [] {
   absl::BitGen gen;
-  static_assert(sizeof(entropy) % sizeof(uint64_t) == 0, "");
+  static_assert(sizeof(entropy) % sizeof(uint64_t) == 0);
   for (int i = 0; i != sizeof(entropy); i += sizeof(uint64_t)) {
     auto rand = absl::Uniform<uint64_t>(gen);
     memcpy(&entropy[i], &rand, sizeof(uint64_t));
@@ -365,8 +365,8 @@
 
 template <class T>
 struct PodRand {
-  static_assert(std::is_pod_v<T>, "");
-  static_assert(kEntropySize + sizeof(T) < sizeof(entropy), "");
+  static_assert(std::is_pod_v<T>);
+  static_assert(kEntropySize + sizeof(T) < sizeof(entropy));
 
   T Get(size_t i) const {
     T v;
@@ -377,7 +377,7 @@
 
 template <size_t N>
 struct StringRand {
-  static_assert(kEntropySize + N < sizeof(entropy), "");
+  static_assert(kEntropySize + N < sizeof(entropy));
 
   absl::string_view Get(size_t i) const {
     // This has a small bias towards small numbers. Because max N is ~200 this
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index d20b296..c8d8235 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -923,7 +923,7 @@
     typename H, InvokeTag... Tags,
     typename = typename EnableIfContained<InvokeTag::kHashValue, Tags...>::type>
 H AbslHashValue(H state, CustomHashType<Tags...> t) {
-  static_assert(MinTag<Tags...>::value == InvokeTag::kHashValue, "");
+  static_assert(MinTag<Tags...>::value == InvokeTag::kHashValue);
   return H::combine(std::move(state),
                     t.value + static_cast<int>(InvokeTag::kHashValue));
 }
@@ -949,7 +949,7 @@
   template <InvokeTag... TagsIn, typename = typename EnableIfContained<
                                      InvokeTag::kLegacyHash, TagsIn...>::type>
   size_t operator()(CustomHashType<TagsIn...> t) const {
-    static_assert(MinTag<Tags...>::value == InvokeTag::kLegacyHash, "");
+    static_assert(MinTag<Tags...>::value == InvokeTag::kLegacyHash);
     return t.value + static_cast<int>(InvokeTag::kLegacyHash);
   }
 };
@@ -962,7 +962,7 @@
   template <InvokeTag... TagsIn, typename = typename EnableIfContained<
                                      InvokeTag::kStdHash, TagsIn...>::type>
   size_t operator()(CustomHashType<TagsIn...> t) const {
-    static_assert(MinTag<Tags...>::value == InvokeTag::kStdHash, "");
+    static_assert(MinTag<Tags...>::value == InvokeTag::kStdHash);
     return t.value + static_cast<int>(InvokeTag::kStdHash);
   }
 };
@@ -1041,10 +1041,10 @@
 
 static_assert(sizeof(StructWithPadding) > sizeof(char) + sizeof(int),
               "StructWithPadding doesn't have padding");
-static_assert(std::is_standard_layout_v<StructWithPadding>, "");
+static_assert(std::is_standard_layout_v<StructWithPadding>);
 
 // This check has to be disabled because libstdc++ doesn't support it.
-// static_assert(std::is_trivially_constructible_v<StructWithPadding>, "");
+// static_assert(std::is_trivially_constructible_v<StructWithPadding>);
 
 template <typename T>
 struct ArraySlice {
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 9463746..b17c574 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -31,11 +31,9 @@
 // GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
 // <version> instead, even though <version> is not available in C++17 mode prior
 // to GCC9.
-#if defined(__has_include)
 #if __has_include(<version>)
 #define ABSL_INTERNAL_VERSION_HEADER_AVAILABLE 1
 #endif
-#endif
 
 // For feature testing and determining which headers can be included.
 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
@@ -575,9 +573,7 @@
 #else
   // On other platforms, we assume that pointers-to-members do not have
   // padding.
-#ifdef __cpp_lib_has_unique_object_representations
     static_assert(std::has_unique_object_representations_v<T C::*>);
-#endif  // __cpp_lib_has_unique_object_representations
     return n;
 #endif
   };
diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h
index 51caaf1..9217ec1 100644
--- a/absl/hash/internal/spy_hash_state.h
+++ b/absl/hash/internal/spy_hash_state.h
@@ -48,7 +48,7 @@
 class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
  public:
   SpyHashStateImpl() : error_(std::make_shared<std::optional<std::string>>()) {
-    static_assert(std::is_void_v<T>, "");
+    static_assert(std::is_void_v<T>);
   }
 
   // Move-only
diff --git a/absl/log/internal/log_format.cc b/absl/log/internal/log_format.cc
index d54cf19..c7bb3ec 100644
--- a/absl/log/internal/log_format.cc
+++ b/absl/log/internal/log_format.cc
@@ -47,29 +47,25 @@
 namespace log_internal {
 namespace {
 
-// This templated function avoids compiler warnings about tautological
-// comparisons when log_internal::Tid is unsigned. It can be replaced with a
-// constexpr if once the minimum C++ version Abseil supports is C++17.
+// The `if constexpr` avoids compiler warnings about tautological comparisons
+// when log_internal::Tid is unsigned.
 template <typename T>
-inline std::enable_if_t<!std::is_signed_v<T>> PutLeadingWhitespace(T tid,
-                                                                   char*& p) {
-  if (tid < 10) *p++ = ' ';
-  if (tid < 100) *p++ = ' ';
-  if (tid < 1000) *p++ = ' ';
-  if (tid < 10000) *p++ = ' ';
-  if (tid < 100000) *p++ = ' ';
-  if (tid < 1000000) *p++ = ' ';
-}
-
-template <typename T>
-inline std::enable_if_t<std::is_signed_v<T>> PutLeadingWhitespace(T tid,
-                                                                  char*& p) {
-  if (tid >= 0 && tid < 10) *p++ = ' ';
-  if (tid > -10 && tid < 100) *p++ = ' ';
-  if (tid > -100 && tid < 1000) *p++ = ' ';
-  if (tid > -1000 && tid < 10000) *p++ = ' ';
-  if (tid > -10000 && tid < 100000) *p++ = ' ';
-  if (tid > -100000 && tid < 1000000) *p++ = ' ';
+inline void PutLeadingWhitespace(T tid, char*& p) {
+  if constexpr (std::is_signed_v<T>) {
+    if (tid >= 0 && tid < 10) *p++ = ' ';
+    if (tid > -10 && tid < 100) *p++ = ' ';
+    if (tid > -100 && tid < 1000) *p++ = ' ';
+    if (tid > -1000 && tid < 10000) *p++ = ' ';
+    if (tid > -10000 && tid < 100000) *p++ = ' ';
+    if (tid > -100000 && tid < 1000000) *p++ = ' ';
+  } else {
+    if (tid < 10) *p++ = ' ';
+    if (tid < 100) *p++ = ' ';
+    if (tid < 1000) *p++ = ' ';
+    if (tid < 10000) *p++ = ' ';
+    if (tid < 100000) *p++ = ' ';
+    if (tid < 1000000) *p++ = ' ';
+  }
 }
 
 // The fields before the filename are all fixed-width except for the thread ID,
diff --git a/absl/log/internal/vlog_config_benchmark.cc b/absl/log/internal/vlog_config_benchmark.cc
index 2634ca3..1916e2c 100644
--- a/absl/log/internal/vlog_config_benchmark.cc
+++ b/absl/log/internal/vlog_config_benchmark.cc
@@ -115,7 +115,7 @@
     sites[num_tus - 1]->next_.store(nullptr, std::memory_order_seq_cst);
   }
   ~SyntheticBinary() {
-    static_assert(std::is_trivially_destructible_v<VLogSite>, "");
+    static_assert(std::is_trivially_destructible_v<VLogSite>);
     absl::log_internal::SetVModuleListHeadForTestOnly(nullptr);
   }
 
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index 6ca2dc8..11701e2 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -17,7 +17,7 @@
 // type_traits.h
 // -----------------------------------------------------------------------------
 //
-// This file contains C++11-compatible versions of standard <type_traits> API
+// This file contains C++17-compatible versions of standard <type_traits> API
 // functions for determining the characteristics of types. Such traits can
 // support type inference, classification, and transformation, as well as
 // make it easier to write templates based on generic type behavior.
@@ -54,13 +54,9 @@
 #include <span>  // NOLINT(build/c++20)
 #endif
 
-// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17
-// feature.
-#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
+// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is
+// predefined by every C++17 implementation.
 #define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__
-#else  // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
-#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t)
-#endif  // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -241,7 +237,7 @@
 #else
 // remove_cvref()
 //
-// C++11 compatible implementation of std::remove_cvref which was added in
+// C++17 compatible implementation of std::remove_cvref which was added in
 // C++20.
 template <typename T>
 struct remove_cvref {
@@ -276,22 +272,16 @@
 
 namespace type_traits_internal {
 
-#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \
-    (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
-// std::result_of is deprecated (C++17) or removed (C++20)
 template <typename>
 struct result_of;
 template <typename F, typename... Args>
 struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};
-#else
-template <typename F>
-using result_of = std::result_of<F>;
-#endif
 
 }  // namespace type_traits_internal
 
 template <typename F>
-using result_of_t = typename type_traits_internal::result_of<F>::type;
+using result_of_t [[deprecated("Use std::invoke_result_t instead.")]] =
+    typename type_traits_internal::result_of<F>::type;
 
 namespace type_traits_internal {
 
@@ -347,68 +337,12 @@
   Helper::Sink(Helper::DoIt<Ts>()...);
 }
 
-}  // namespace type_traits_internal
-
-// An internal namespace that is required to implement the C++17 swap traits.
-// It is not further nested in type_traits_internal to avoid long symbol names.
-namespace swap_internal {
-
-// Necessary for the traits.
-using std::swap;
-
-// This declaration prevents global `swap` and `absl::swap` overloads from being
-// considered unless ADL picks them up.
-void swap();
+template <class T>
+using IsSwappable ABSL_DEPRECATE_AND_INLINE() = std::is_swappable<T>;
 
 template <class T>
-using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>()));
-
-// NOTE: This dance with the default template parameter is for MSVC.
-template <class T, class IsNoexcept = std::bool_constant<noexcept(
-                       swap(std::declval<T&>(), std::declval<T&>()))>>
-using IsNothrowSwappableImpl = std::enable_if_t<IsNoexcept::value>;
-
-// IsSwappable
-//
-// Determines whether the standard swap idiom is a valid expression for
-// arguments of type `T`.
-template <class T>
-struct IsSwappable
-    : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {};
-
-// IsNothrowSwappable
-//
-// Determines whether the standard swap idiom is a valid expression for
-// arguments of type `T` and is noexcept.
-template <class T>
-struct IsNothrowSwappable
-    : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {};
-
-// Swap()
-//
-// Performs the swap idiom from a namespace where valid candidates may only be
-// found in `std` or via ADL.
-template <class T, std::enable_if_t<IsSwappable<T>::value, int> = 0>
-void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) {
-  swap(lhs, rhs);
-}
-
-// StdSwapIsUnconstrained
-//
-// Some standard library implementations are broken in that they do not
-// constrain `std::swap`. This will effectively tell us if we are dealing with
-// one of those implementations.
-using StdSwapIsUnconstrained = IsSwappable<void()>;
-
-}  // namespace swap_internal
-
-namespace type_traits_internal {
-
-// Make the swap-related traits/function accessible from this namespace.
-using swap_internal::IsNothrowSwappable;
-using swap_internal::IsSwappable;
-using swap_internal::StdSwapIsUnconstrained;
-using swap_internal::Swap;
+using IsNothrowSwappable ABSL_DEPRECATE_AND_INLINE() =
+    std::is_nothrow_swappable<T>;
 
 }  // namespace type_traits_internal
 
@@ -484,10 +418,9 @@
 // TODO(b/325479096): Remove this case.
 template <class T>
 struct is_trivially_relocatable
-    : std::integral_constant<bool,
-                             std::is_trivially_copyable_v<T> ||
-                                 (__is_trivially_relocatable(T) &&
-                                  std::is_trivially_move_assignable_v<T>)> {};
+    : std::bool_constant<std::is_trivially_copyable_v<T> ||
+                         (__is_trivially_relocatable(T) &&
+                          std::is_trivially_move_assignable_v<T>)> {};
 #else
 // Otherwise we use a fallback that detects only those types we can feasibly
 // detect. Any type that is trivially copyable is by definition trivially
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 3675a0f..a11049c 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -184,7 +184,7 @@
 
 struct GetTypeExtT {
   template <typename T>
-  absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const {
+  std::invoke_result_t<const GetTypeT&, T> operator()(T&& arg) const {
     return GetType(std::forward<T>(arg));
   }
 
@@ -216,7 +216,6 @@
 
 TEST(TypeTraitsTest, IsSwappable) {
   using absl::type_traits_internal::IsSwappable;
-  using absl::type_traits_internal::StdSwapIsUnconstrained;
 
   EXPECT_TRUE(IsSwappable<int>::value);
 
@@ -229,14 +228,14 @@
     ~NoConstruct() = default;
   };
 
-  EXPECT_EQ(IsSwappable<NoConstruct>::value, StdSwapIsUnconstrained::value);
+  EXPECT_FALSE(IsSwappable<NoConstruct>::value);
   struct NoAssign {
     NoAssign(NoAssign&&) {}
     NoAssign& operator=(NoAssign&&) = delete;
     ~NoAssign() = default;
   };
 
-  EXPECT_EQ(IsSwappable<NoAssign>::value, StdSwapIsUnconstrained::value);
+  EXPECT_FALSE(IsSwappable<NoAssign>::value);
 
   EXPECT_FALSE(IsSwappable<adl_namespace::DeletedSwap>::value);
 
@@ -245,7 +244,6 @@
 
 TEST(TypeTraitsTest, IsNothrowSwappable) {
   using absl::type_traits_internal::IsNothrowSwappable;
-  using absl::type_traits_internal::StdSwapIsUnconstrained;
 
   EXPECT_TRUE(IsNothrowSwappable<int>::value);
 
@@ -279,9 +277,9 @@
 }
 
 TEST(TriviallyRelocatable, PrimitiveTypes) {
-  static_assert(absl::is_trivially_relocatable<int>::value, "");
-  static_assert(absl::is_trivially_relocatable<char>::value, "");
-  static_assert(absl::is_trivially_relocatable<void*>::value, "");
+  static_assert(absl::is_trivially_relocatable<int>::value);
+  static_assert(absl::is_trivially_relocatable<char>::value);
+  static_assert(absl::is_trivially_relocatable<void*>::value);
 }
 
 // User-defined types can be trivially relocatable as long as they don't have a
@@ -292,7 +290,7 @@
     int y;
   };
 
-  static_assert(absl::is_trivially_relocatable<S>::value, "");
+  static_assert(absl::is_trivially_relocatable<S>::value);
 }
 
 // A user-provided move constructor disqualifies a type from being trivially
@@ -302,7 +300,7 @@
     S(S&&) {}  // NOLINT(modernize-use-equals-default)
   };
 
-  static_assert(!absl::is_trivially_relocatable<S>::value, "");
+  static_assert(!absl::is_trivially_relocatable<S>::value);
 }
 
 // A user-provided copy constructor disqualifies a type from being trivially
@@ -312,7 +310,7 @@
     S(const S&) {}  // NOLINT(modernize-use-equals-default)
   };
 
-  static_assert(!absl::is_trivially_relocatable<S>::value, "");
+  static_assert(!absl::is_trivially_relocatable<S>::value);
 }
 
 // A user-provided copy assignment operator disqualifies a type from
@@ -325,7 +323,7 @@
     }
   };
 
-  static_assert(!absl::is_trivially_relocatable<S>::value, "");
+  static_assert(!absl::is_trivially_relocatable<S>::value);
 }
 
 // A user-provided move assignment operator disqualifies a type from
@@ -336,7 +334,7 @@
     S& operator=(S&&) { return *this; }  // NOLINT(modernize-use-equals-default)
   };
 
-  static_assert(!absl::is_trivially_relocatable<S>::value, "");
+  static_assert(!absl::is_trivially_relocatable<S>::value);
 }
 
 // A user-provided destructor disqualifies a type from being trivially
@@ -346,7 +344,7 @@
     ~S() {}  // NOLINT(modernize-use-equals-default)
   };
 
-  static_assert(!absl::is_trivially_relocatable<S>::value, "");
+  static_assert(!absl::is_trivially_relocatable<S>::value);
 }
 
 TEST(Ownership, References) {
diff --git a/absl/numeric/bits_test.cc b/absl/numeric/bits_test.cc
index e2c6409..8cf2378 100644
--- a/absl/numeric/bits_test.cc
+++ b/absl/numeric/bits_test.cc
@@ -62,32 +62,32 @@
 
   EXPECT_EQ(rotl(UIntType{0x12}, 0), uint8_t{0x12});
   EXPECT_EQ(rotr(UIntType{0x12}, -4), uint8_t{0x21});
-  static_assert(rotl(UIntType{0x12}, 0) == uint8_t{0x12}, "");
+  static_assert(rotl(UIntType{0x12}, 0) == uint8_t{0x12});
 
-  static_assert(rotr(UIntType{0x12}, 0) == uint8_t{0x12}, "");
+  static_assert(rotr(UIntType{0x12}, 0) == uint8_t{0x12});
   EXPECT_EQ(rotr(UIntType{0x12}, 0), uint8_t{0x12});
 
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
-  static_assert(countl_zero(UIntType{}) == 8, "");
-  static_assert(countl_zero(static_cast<UIntType>(-1)) == 0, "");
+  static_assert(countl_zero(UIntType{}) == 8);
+  static_assert(countl_zero(static_cast<UIntType>(-1)) == 0);
 
-  static_assert(countl_one(UIntType{}) == 0, "");
-  static_assert(countl_one(static_cast<UIntType>(-1)) == 8, "");
+  static_assert(countl_one(UIntType{}) == 0);
+  static_assert(countl_one(static_cast<UIntType>(-1)) == 8);
 
-  static_assert(countr_zero(UIntType{}) == 8, "");
-  static_assert(countr_zero(static_cast<UIntType>(-1)) == 0, "");
+  static_assert(countr_zero(UIntType{}) == 8);
+  static_assert(countr_zero(static_cast<UIntType>(-1)) == 0);
 
-  static_assert(countr_one(UIntType{}) == 0, "");
-  static_assert(countr_one(static_cast<UIntType>(-1)) == 8, "");
+  static_assert(countr_one(UIntType{}) == 0);
+  static_assert(countr_one(static_cast<UIntType>(-1)) == 8);
 
-  static_assert(popcount(UIntType{}) == 0, "");
-  static_assert(popcount(UIntType{1}) == 1, "");
-  static_assert(popcount(static_cast<UIntType>(-1)) == 8, "");
+  static_assert(popcount(UIntType{}) == 0);
+  static_assert(popcount(UIntType{1}) == 1);
+  static_assert(popcount(static_cast<UIntType>(-1)) == 8);
 
-  static_assert(bit_width(UIntType{}) == 0, "");
-  static_assert(bit_width(UIntType{1}) == 1, "");
-  static_assert(bit_width(UIntType{3}) == 2, "");
-  static_assert(bit_width(static_cast<UIntType>(-1)) == 8, "");
+  static_assert(bit_width(UIntType{}) == 0);
+  static_assert(bit_width(UIntType{1}) == 1);
+  static_assert(bit_width(UIntType{3}) == 2);
+  static_assert(bit_width(static_cast<UIntType>(-1)) == 8);
 #endif
 
   EXPECT_EQ(countl_zero(UIntType{}), 8);
@@ -115,12 +115,11 @@
 }
 
 TEST(Rotate, Left) {
-  static_assert(rotl(uint8_t{0x12}, 0) == uint8_t{0x12}, "");
-  static_assert(rotl(uint16_t{0x1234}, 0) == uint16_t{0x1234}, "");
-  static_assert(rotl(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}, "");
+  static_assert(rotl(uint8_t{0x12}, 0) == uint8_t{0x12});
+  static_assert(rotl(uint16_t{0x1234}, 0) == uint16_t{0x1234});
+  static_assert(rotl(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL});
   static_assert(rotl(uint64_t{0x12345678ABCDEF01ULL}, 0) ==
-                    uint64_t{0x12345678ABCDEF01ULL},
-                "");
+                uint64_t{0x12345678ABCDEF01ULL});
 
   EXPECT_EQ(rotl(uint8_t{0x12}, 0), uint8_t{0x12});
   EXPECT_EQ(rotl(uint16_t{0x1234}, 0), uint16_t{0x1234});
@@ -157,12 +156,11 @@
 }
 
 TEST(Rotate, Right) {
-  static_assert(rotr(uint8_t{0x12}, 0) == uint8_t{0x12}, "");
-  static_assert(rotr(uint16_t{0x1234}, 0) == uint16_t{0x1234}, "");
-  static_assert(rotr(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}, "");
+  static_assert(rotr(uint8_t{0x12}, 0) == uint8_t{0x12});
+  static_assert(rotr(uint16_t{0x1234}, 0) == uint16_t{0x1234});
+  static_assert(rotr(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL});
   static_assert(rotr(uint64_t{0x12345678ABCDEF01ULL}, 0) ==
-                    uint64_t{0x12345678ABCDEF01ULL},
-                "");
+                uint64_t{0x12345678ABCDEF01ULL});
 
   EXPECT_EQ(rotr(uint8_t{0x12}, 0), uint8_t{0x12});
   EXPECT_EQ(rotr(uint16_t{0x1234}, 0), uint16_t{0x1234});
@@ -242,14 +240,14 @@
 
 TEST(Counting, LeadingZeroes) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
-  static_assert(countl_zero(uint8_t{}) == 8, "");
-  static_assert(countl_zero(static_cast<uint8_t>(-1)) == 0, "");
-  static_assert(countl_zero(uint16_t{}) == 16, "");
-  static_assert(countl_zero(static_cast<uint16_t>(-1)) == 0, "");
-  static_assert(countl_zero(uint32_t{}) == 32, "");
-  static_assert(countl_zero(~uint32_t{}) == 0, "");
-  static_assert(countl_zero(uint64_t{}) == 64, "");
-  static_assert(countl_zero(~uint64_t{}) == 0, "");
+  static_assert(countl_zero(uint8_t{}) == 8);
+  static_assert(countl_zero(static_cast<uint8_t>(-1)) == 0);
+  static_assert(countl_zero(uint16_t{}) == 16);
+  static_assert(countl_zero(static_cast<uint16_t>(-1)) == 0);
+  static_assert(countl_zero(uint32_t{}) == 32);
+  static_assert(countl_zero(~uint32_t{}) == 0);
+  static_assert(countl_zero(uint64_t{}) == 64);
+  static_assert(countl_zero(~uint64_t{}) == 0);
 #endif
 
   EXPECT_EQ(countl_zero(uint8_t{}), 8);
@@ -280,14 +278,14 @@
 
 TEST(Counting, LeadingOnes) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
-  static_assert(countl_one(uint8_t{}) == 0, "");
-  static_assert(countl_one(static_cast<uint8_t>(-1)) == 8, "");
-  static_assert(countl_one(uint16_t{}) == 0, "");
-  static_assert(countl_one(static_cast<uint16_t>(-1)) == 16, "");
-  static_assert(countl_one(uint32_t{}) == 0, "");
-  static_assert(countl_one(~uint32_t{}) == 32, "");
-  static_assert(countl_one(uint64_t{}) == 0, "");
-  static_assert(countl_one(~uint64_t{}) == 64, "");
+  static_assert(countl_one(uint8_t{}) == 0);
+  static_assert(countl_one(static_cast<uint8_t>(-1)) == 8);
+  static_assert(countl_one(uint16_t{}) == 0);
+  static_assert(countl_one(static_cast<uint16_t>(-1)) == 16);
+  static_assert(countl_one(uint32_t{}) == 0);
+  static_assert(countl_one(~uint32_t{}) == 32);
+  static_assert(countl_one(uint64_t{}) == 0);
+  static_assert(countl_one(~uint64_t{}) == 64);
 #endif
 
   EXPECT_EQ(countl_one(uint8_t{}), 0);
@@ -302,14 +300,14 @@
 
 TEST(Counting, TrailingZeroes) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CTZ
-  static_assert(countr_zero(uint8_t{}) == 8, "");
-  static_assert(countr_zero(static_cast<uint8_t>(-1)) == 0, "");
-  static_assert(countr_zero(uint16_t{}) == 16, "");
-  static_assert(countr_zero(static_cast<uint16_t>(-1)) == 0, "");
-  static_assert(countr_zero(uint32_t{}) == 32, "");
-  static_assert(countr_zero(~uint32_t{}) == 0, "");
-  static_assert(countr_zero(uint64_t{}) == 64, "");
-  static_assert(countr_zero(~uint64_t{}) == 0, "");
+  static_assert(countr_zero(uint8_t{}) == 8);
+  static_assert(countr_zero(static_cast<uint8_t>(-1)) == 0);
+  static_assert(countr_zero(uint16_t{}) == 16);
+  static_assert(countr_zero(static_cast<uint16_t>(-1)) == 0);
+  static_assert(countr_zero(uint32_t{}) == 32);
+  static_assert(countr_zero(~uint32_t{}) == 0);
+  static_assert(countr_zero(uint64_t{}) == 64);
+  static_assert(countr_zero(~uint64_t{}) == 0);
 #endif
 
   EXPECT_EQ(countr_zero(uint8_t{}), 8);
@@ -324,14 +322,14 @@
 
 TEST(Counting, TrailingOnes) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CTZ
-  static_assert(countr_one(uint8_t{}) == 0, "");
-  static_assert(countr_one(static_cast<uint8_t>(-1)) == 8, "");
-  static_assert(countr_one(uint16_t{}) == 0, "");
-  static_assert(countr_one(static_cast<uint16_t>(-1)) == 16, "");
-  static_assert(countr_one(uint32_t{}) == 0, "");
-  static_assert(countr_one(~uint32_t{}) == 32, "");
-  static_assert(countr_one(uint64_t{}) == 0, "");
-  static_assert(countr_one(~uint64_t{}) == 64, "");
+  static_assert(countr_one(uint8_t{}) == 0);
+  static_assert(countr_one(static_cast<uint8_t>(-1)) == 8);
+  static_assert(countr_one(uint16_t{}) == 0);
+  static_assert(countr_one(static_cast<uint16_t>(-1)) == 16);
+  static_assert(countr_one(uint32_t{}) == 0);
+  static_assert(countr_one(~uint32_t{}) == 32);
+  static_assert(countr_one(uint64_t{}) == 0);
+  static_assert(countr_one(~uint64_t{}) == 64);
 #endif
 
   EXPECT_EQ(countr_one(uint8_t{}), 0);
@@ -346,18 +344,18 @@
 
 TEST(Counting, Popcount) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT
-  static_assert(popcount(uint8_t{}) == 0, "");
-  static_assert(popcount(uint8_t{1}) == 1, "");
-  static_assert(popcount(static_cast<uint8_t>(-1)) == 8, "");
-  static_assert(popcount(uint16_t{}) == 0, "");
-  static_assert(popcount(uint16_t{1}) == 1, "");
-  static_assert(popcount(static_cast<uint16_t>(-1)) == 16, "");
-  static_assert(popcount(uint32_t{}) == 0, "");
-  static_assert(popcount(uint32_t{1}) == 1, "");
-  static_assert(popcount(~uint32_t{}) == 32, "");
-  static_assert(popcount(uint64_t{}) == 0, "");
-  static_assert(popcount(uint64_t{1}) == 1, "");
-  static_assert(popcount(~uint64_t{}) == 64, "");
+  static_assert(popcount(uint8_t{}) == 0);
+  static_assert(popcount(uint8_t{1}) == 1);
+  static_assert(popcount(static_cast<uint8_t>(-1)) == 8);
+  static_assert(popcount(uint16_t{}) == 0);
+  static_assert(popcount(uint16_t{1}) == 1);
+  static_assert(popcount(static_cast<uint16_t>(-1)) == 16);
+  static_assert(popcount(uint32_t{}) == 0);
+  static_assert(popcount(uint32_t{1}) == 1);
+  static_assert(popcount(~uint32_t{}) == 32);
+  static_assert(popcount(uint64_t{}) == 0);
+  static_assert(popcount(uint64_t{1}) == 1);
+  static_assert(popcount(~uint64_t{}) == 64);
 #endif  // ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT
 
   EXPECT_EQ(popcount(uint8_t{}), 0);
@@ -452,15 +450,15 @@
   EXPECT_FALSE(has_single_bit(uint64_t{}));
   EXPECT_FALSE(has_single_bit(~uint64_t{}));
 
-  static_assert(!has_single_bit(0u), "");
-  static_assert(has_single_bit(1u), "");
-  static_assert(has_single_bit(2u), "");
-  static_assert(!has_single_bit(3u), "");
-  static_assert(has_single_bit(4u), "");
-  static_assert(!has_single_bit(1337u), "");
-  static_assert(has_single_bit(65536u), "");
-  static_assert(has_single_bit(uint32_t{1} << 30), "");
-  static_assert(has_single_bit(uint64_t{1} << 42), "");
+  static_assert(!has_single_bit(0u));
+  static_assert(has_single_bit(1u));
+  static_assert(has_single_bit(2u));
+  static_assert(!has_single_bit(3u));
+  static_assert(has_single_bit(4u));
+  static_assert(!has_single_bit(1337u));
+  static_assert(has_single_bit(65536u));
+  static_assert(has_single_bit(uint32_t{1} << 30));
+  static_assert(has_single_bit(uint64_t{1} << 42));
 
   EXPECT_FALSE(has_single_bit(0u));
   EXPECT_TRUE(has_single_bit(1u));
@@ -493,20 +491,18 @@
 
 TEST(IntegralPowersOfTwo, Ceiling) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
-  static_assert(bit_ceil(0u) == 1, "");
-  static_assert(bit_ceil(1u) == 1, "");
-  static_assert(bit_ceil(2u) == 2, "");
-  static_assert(bit_ceil(3u) == 4, "");
-  static_assert(bit_ceil(4u) == 4, "");
-  static_assert(bit_ceil(1337u) == 2048, "");
-  static_assert(bit_ceil(65536u) == 65536, "");
-  static_assert(bit_ceil(65536u - 1337u) == 65536, "");
-  static_assert(bit_ceil(uint32_t{0x80000000}) == uint32_t{0x80000000}, "");
-  static_assert(bit_ceil(uint64_t{0x40000000000}) == uint64_t{0x40000000000},
-                "");
-  static_assert(
-      bit_ceil(uint64_t{0x8000000000000000}) == uint64_t{0x8000000000000000},
-      "");
+  static_assert(bit_ceil(0u) == 1);
+  static_assert(bit_ceil(1u) == 1);
+  static_assert(bit_ceil(2u) == 2);
+  static_assert(bit_ceil(3u) == 4);
+  static_assert(bit_ceil(4u) == 4);
+  static_assert(bit_ceil(1337u) == 2048);
+  static_assert(bit_ceil(65536u) == 65536);
+  static_assert(bit_ceil(65536u - 1337u) == 65536);
+  static_assert(bit_ceil(uint32_t{0x80000000}) == uint32_t{0x80000000});
+  static_assert(bit_ceil(uint64_t{0x40000000000}) == uint64_t{0x40000000000});
+  static_assert(bit_ceil(uint64_t{0x8000000000000000}) ==
+                uint64_t{0x8000000000000000});
 
   EXPECT_TRUE((IsBitCeilConstantExpression<uint8_t, uint8_t{0x0}>(0)));
   EXPECT_TRUE((IsBitCeilConstantExpression<uint8_t, uint8_t{0x80}>(0)));
@@ -547,16 +543,15 @@
 
 TEST(IntegralPowersOfTwo, Floor) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
-  static_assert(bit_floor(0u) == 0, "");
-  static_assert(bit_floor(1u) == 1, "");
-  static_assert(bit_floor(2u) == 2, "");
-  static_assert(bit_floor(3u) == 2, "");
-  static_assert(bit_floor(4u) == 4, "");
-  static_assert(bit_floor(1337u) == 1024, "");
-  static_assert(bit_floor(65536u) == 65536, "");
-  static_assert(bit_floor(65536u - 1337u) == 32768, "");
-  static_assert(bit_floor(uint64_t{0x40000000000}) == uint64_t{0x40000000000},
-                "");
+  static_assert(bit_floor(0u) == 0);
+  static_assert(bit_floor(1u) == 1);
+  static_assert(bit_floor(2u) == 2);
+  static_assert(bit_floor(3u) == 2);
+  static_assert(bit_floor(4u) == 4);
+  static_assert(bit_floor(1337u) == 1024);
+  static_assert(bit_floor(65536u) == 65536);
+  static_assert(bit_floor(65536u - 1337u) == 32768);
+  static_assert(bit_floor(uint64_t{0x40000000000}) == uint64_t{0x40000000000});
 #endif
 
   EXPECT_EQ(bit_floor(0u), 0);
@@ -604,22 +599,22 @@
 
 TEST(IntegralPowersOfTwo, Width) {
 #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
-  static_assert(bit_width(uint8_t{}) == 0, "");
-  static_assert(bit_width(uint8_t{1}) == 1, "");
-  static_assert(bit_width(uint8_t{3}) == 2, "");
-  static_assert(bit_width(static_cast<uint8_t>(-1)) == 8, "");
-  static_assert(bit_width(uint16_t{}) == 0, "");
-  static_assert(bit_width(uint16_t{1}) == 1, "");
-  static_assert(bit_width(uint16_t{3}) == 2, "");
-  static_assert(bit_width(static_cast<uint16_t>(-1)) == 16, "");
-  static_assert(bit_width(uint32_t{}) == 0, "");
-  static_assert(bit_width(uint32_t{1}) == 1, "");
-  static_assert(bit_width(uint32_t{3}) == 2, "");
-  static_assert(bit_width(~uint32_t{}) == 32, "");
-  static_assert(bit_width(uint64_t{}) == 0, "");
-  static_assert(bit_width(uint64_t{1}) == 1, "");
-  static_assert(bit_width(uint64_t{3}) == 2, "");
-  static_assert(bit_width(~uint64_t{}) == 64, "");
+  static_assert(bit_width(uint8_t{}) == 0);
+  static_assert(bit_width(uint8_t{1}) == 1);
+  static_assert(bit_width(uint8_t{3}) == 2);
+  static_assert(bit_width(static_cast<uint8_t>(-1)) == 8);
+  static_assert(bit_width(uint16_t{}) == 0);
+  static_assert(bit_width(uint16_t{1}) == 1);
+  static_assert(bit_width(uint16_t{3}) == 2);
+  static_assert(bit_width(static_cast<uint16_t>(-1)) == 16);
+  static_assert(bit_width(uint32_t{}) == 0);
+  static_assert(bit_width(uint32_t{1}) == 1);
+  static_assert(bit_width(uint32_t{3}) == 2);
+  static_assert(bit_width(~uint32_t{}) == 32);
+  static_assert(bit_width(uint64_t{}) == 0);
+  static_assert(bit_width(uint64_t{1}) == 1);
+  static_assert(bit_width(uint64_t{3}) == 2);
+  static_assert(bit_width(~uint64_t{}) == 64);
 #endif
 
   EXPECT_EQ(bit_width(uint8_t{}), 0);
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc
index 9987c15..5dfc5ea 100644
--- a/absl/numeric/int128.cc
+++ b/absl/numeric/int128.cc
@@ -90,7 +90,7 @@
 
 template <typename T>
 uint128 MakeUint128FromFloat(T v) {
-  static_assert(std::is_floating_point_v<T>, "");
+  static_assert(std::is_floating_point_v<T>);
 
   // Rounding behavior is towards zero, same as for built-in types.
 
@@ -114,8 +114,8 @@
 // It is more work, so only use when we need the workaround.
 uint128 MakeUint128FromFloat(long double v) {
   // Go 50 bits at a time, that fits in a double
-  static_assert(std::numeric_limits<double>::digits >= 50, "");
-  static_assert(std::numeric_limits<long double>::digits <= 150, "");
+  static_assert(std::numeric_limits<double>::digits >= 50);
+  static_assert(std::numeric_limits<long double>::digits <= 150);
   // Undefined behavior if v is not finite or cannot fit into uint128.
   assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128));
 
diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc
index 35eacae..9c140f0 100644
--- a/absl/numeric/int128_test.cc
+++ b/absl/numeric/int128_test.cc
@@ -93,10 +93,10 @@
 #endif  // ABSL_HAVE_INTRINSIC_INT128
 
 TEST(Uint128, TrivialTraitsTest) {
-  static_assert(std::is_trivially_default_constructible_v<absl::uint128>, "");
-  static_assert(std::is_trivially_copy_constructible_v<absl::uint128>, "");
-  static_assert(std::is_trivially_copy_assignable_v<absl::uint128>, "");
-  static_assert(std::is_trivially_destructible_v<absl::uint128>, "");
+  static_assert(std::is_trivially_default_constructible_v<absl::uint128>);
+  static_assert(std::is_trivially_copy_constructible_v<absl::uint128>);
+  static_assert(std::is_trivially_copy_assignable_v<absl::uint128>);
+  static_assert(std::is_trivially_destructible_v<absl::uint128>);
 }
 
 TEST(Uint128, AllTests) {
@@ -483,9 +483,9 @@
 }
 
 TEST(Uint128, NumericLimitsTest) {
-  static_assert(std::numeric_limits<absl::uint128>::is_specialized, "");
-  static_assert(!std::numeric_limits<absl::uint128>::is_signed, "");
-  static_assert(std::numeric_limits<absl::uint128>::is_integer, "");
+  static_assert(std::numeric_limits<absl::uint128>::is_specialized);
+  static_assert(!std::numeric_limits<absl::uint128>::is_signed);
+  static_assert(std::numeric_limits<absl::uint128>::is_integer);
   EXPECT_EQ(static_cast<int>(128 * std::log10(2)),
             std::numeric_limits<absl::uint128>::digits10);
   EXPECT_EQ(0, std::numeric_limits<absl::uint128>::min());
@@ -617,10 +617,10 @@
 #endif  // ABSL_HAVE_INTRINSIC_INT128
 
 TEST(Int128, TrivialTraitsTest) {
-  static_assert(std::is_trivially_default_constructible_v<absl::int128>, "");
-  static_assert(std::is_trivially_copy_constructible_v<absl::int128>, "");
-  static_assert(std::is_trivially_copy_assignable_v<absl::int128>, "");
-  static_assert(std::is_trivially_destructible_v<absl::int128>, "");
+  static_assert(std::is_trivially_default_constructible_v<absl::int128>);
+  static_assert(std::is_trivially_copy_constructible_v<absl::int128>);
+  static_assert(std::is_trivially_copy_assignable_v<absl::int128>);
+  static_assert(std::is_trivially_destructible_v<absl::int128>);
 }
 
 TEST(Int128, BoolConversionTest) {
@@ -1345,9 +1345,9 @@
 }
 
 TEST(Int128, NumericLimitsTest) {
-  static_assert(std::numeric_limits<absl::int128>::is_specialized, "");
-  static_assert(std::numeric_limits<absl::int128>::is_signed, "");
-  static_assert(std::numeric_limits<absl::int128>::is_integer, "");
+  static_assert(std::numeric_limits<absl::int128>::is_specialized);
+  static_assert(std::numeric_limits<absl::int128>::is_signed);
+  static_assert(std::numeric_limits<absl::int128>::is_integer);
   EXPECT_EQ(static_cast<int>(127 * std::log10(2)),
             std::numeric_limits<absl::int128>::digits10);
   EXPECT_EQ(absl::Int128Min(), std::numeric_limits<absl::int128>::min());
diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h
index 15311df..a2cdd25 100644
--- a/absl/random/beta_distribution.h
+++ b/absl/random/beta_distribution.h
@@ -23,7 +23,6 @@
 #include <ostream>
 #include <type_traits>
 
-#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/meta/type_traits.h"
 #include "absl/random/internal/fast_uniform_bits.h"
@@ -387,7 +386,6 @@
     case param_type::JOEHNK:
       return AlgorithmJoehnk(g, p);
     case param_type::CHENG_BA:
-      ABSL_FALLTHROUGH_INTENDED;
     case param_type::CHENG_BB:
       return AlgorithmCheng(g, p);
     default:
diff --git a/absl/random/distributions_test.cc b/absl/random/distributions_test.cc
index 16c9e2e..9b081e9 100644
--- a/absl/random/distributions_test.cc
+++ b/absl/random/distributions_test.cc
@@ -82,15 +82,13 @@
   static_assert(
       std::conjunction_v<
           std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
-          std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>,
-      "");
+          std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>);
   static_assert(
       std::conjunction_v<
           std::is_same<Expect, decltype(InferredTaggedUniformReturnT<
                                         absl::IntervalOpenOpenTag, A, B>(0))>,
           std::is_same<Expect, decltype(InferredTaggedUniformReturnT<
-                                        absl::IntervalOpenOpenTag, B, A>(0))>>,
-      "");
+                                        absl::IntervalOpenOpenTag, B, A>(0))>>);
 }
 
 template <typename A, typename B, typename ExplicitRet>
@@ -123,8 +121,7 @@
           std::is_same<Expect,
                        decltype(ExplicitUniformReturnT<A, B, Expect>(0))>,
           std::is_same<Expect,
-                       decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>,
-      "");
+                       decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>);
   static_assert(
       std::conjunction_v<
           std::is_same<Expect,
@@ -132,8 +129,7 @@
                                 absl::IntervalOpenOpenTag, A, B, Expect>(0))>,
           std::is_same<Expect,
                        decltype(ExplicitTaggedUniformReturnT<
-                                absl::IntervalOpenOpenTag, B, A, Expect>(0))>>,
-      "");
+                                absl::IntervalOpenOpenTag, B, A, Expect>(0))>>);
 }
 
 // Takes the type of `absl::Uniform<R>(gen)` if valid or `Invalid` otherwise.
diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h
index e016946..6af0455 100644
--- a/absl/random/internal/generate_real.h
+++ b/absl/random/internal/generate_real.h
@@ -85,8 +85,7 @@
 
   static_assert((std::is_same_v<SignedTag, GeneratePositiveTag> ||
                  std::is_same_v<SignedTag, GenerateNegativeTag> ||
-                 std::is_same_v<SignedTag, GenerateSignedTag>),
-                "");
+                 std::is_same_v<SignedTag, GenerateSignedTag>));
 
   static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
   static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
diff --git a/absl/random/internal/iostream_state_saver.h b/absl/random/internal/iostream_state_saver.h
index 7c11a0b..05d9f83 100644
--- a/absl/random/internal/iostream_state_saver.h
+++ b/absl/random/internal/iostream_state_saver.h
@@ -223,7 +223,7 @@
 
 template <typename FloatType, typename IStream>
 inline FloatType read_floating_point(IStream& is) {
-  static_assert(std::is_floating_point_v<FloatType>, "");
+  static_assert(std::is_floating_point_v<FloatType>);
   FloatType dest;
   is >> dest;
   // Parsing a double value may report a subnormal value as an error
diff --git a/absl/random/internal/randen_detect.cc b/absl/random/internal/randen_detect.cc
index 7d42c6d..fc77b1c 100644
--- a/absl/random/internal/randen_detect.cc
+++ b/absl/random/internal/randen_detect.cc
@@ -20,11 +20,9 @@
 #include "absl/random/internal/randen_detect.h"
 
 #if defined(__APPLE__) && defined(__aarch64__)
-#if defined(__has_include)
 #if __has_include(<arm/cpu_capabilities_public.h>)
 #include <arm/cpu_capabilities_public.h>
 #endif
-#endif
 #include <sys/sysctl.h>
 #include <sys/types.h>
 #endif
diff --git a/absl/random/internal/uniform_helper_test.cc b/absl/random/internal/uniform_helper_test.cc
index bd5acca..e38b3b1 100644
--- a/absl/random/internal/uniform_helper_test.cc
+++ b/absl/random/internal/uniform_helper_test.cc
@@ -217,8 +217,7 @@
   static_assert(
       std::conjunction_v<
           std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
-          std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>,
-      "");
+          std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>);
 }
 
 TEST_F(UniformHelperTest, UniformTypeInference) {
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h
index 03b0663..81f6ce4 100644
--- a/absl/status/internal/status_internal.h
+++ b/absl/status/internal/status_internal.h
@@ -82,6 +82,9 @@
 
 using Payloads = absl::InlinedVector<Payload, 1>;
 
+template <typename T>
+using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>>;
+
 // Reference-counted representation of Status data.
 class StatusRep {
  public:
@@ -92,16 +95,13 @@
         message_(message_arg),
         payloads_(std::move(payloads_arg)) {}
 
-#ifndef SWIG
-  template <typename String,
-            typename = std::enable_if_t<std::is_same_v<String, std::string>>>
+  template <typename String, typename = EnableIfString<String>>
   StatusRep(absl::StatusCode code_arg, String&& message_arg,
             std::unique_ptr<status_internal::Payloads> payloads_arg)
       : ref_(int32_t{1}),
         code_(code_arg),
         message_(std::forward<String>(message_arg)),
         payloads_(std::move(payloads_arg)) {}
-#endif  // SWIG
 
   absl::StatusCode code() const { return code_; }
   const std::string& message() const { return message_; }
diff --git a/absl/status/status.cc b/absl/status/status.cc
index 155c5d8..555ae42 100644
--- a/absl/status/status.cc
+++ b/absl/status/status.cc
@@ -171,7 +171,7 @@
 namespace status_internal {
 // We use an int in the template parameter to shorten mangled names.
 template <int error_code>
-Status MakeErrorImpl(string_view message, SourceLocation loc) {
+Status MakeErrorStringViewImpl(string_view message, SourceLocation loc) {
   return Status(static_cast<StatusCode>(error_code), message, loc);
 }
 
@@ -179,23 +179,55 @@
 // If we add more error code, we need to add their values on this list.
 // Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier
 // to see that the list is complete.
-template Status MakeErrorImpl<0>(string_view, SourceLocation);
-template Status MakeErrorImpl<1>(string_view, SourceLocation);
-template Status MakeErrorImpl<2>(string_view, SourceLocation);
-template Status MakeErrorImpl<3>(string_view, SourceLocation);
-template Status MakeErrorImpl<4>(string_view, SourceLocation);
-template Status MakeErrorImpl<5>(string_view, SourceLocation);
-template Status MakeErrorImpl<6>(string_view, SourceLocation);
-template Status MakeErrorImpl<7>(string_view, SourceLocation);
-template Status MakeErrorImpl<8>(string_view, SourceLocation);
-template Status MakeErrorImpl<9>(string_view, SourceLocation);
-template Status MakeErrorImpl<10>(string_view, SourceLocation);
-template Status MakeErrorImpl<11>(string_view, SourceLocation);
-template Status MakeErrorImpl<12>(string_view, SourceLocation);
-template Status MakeErrorImpl<13>(string_view, SourceLocation);
-template Status MakeErrorImpl<14>(string_view, SourceLocation);
-template Status MakeErrorImpl<15>(string_view, SourceLocation);
-template Status MakeErrorImpl<16>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<0>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<1>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<2>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<3>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<4>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<5>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<6>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<7>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<8>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<9>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<10>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<11>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<12>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<13>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<14>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<15>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<16>(string_view, SourceLocation);
+
+// Same as above, but for rvalue strings.
+#ifndef SWIG
+// We use an int in the template parameter to shorten mangled names.
+template <int error_code>
+Status MakeErrorStringRvalueImpl(std::string&& message, SourceLocation loc) {
+  return Status(static_cast<StatusCode>(error_code), std::move(message), loc);
+}
+
+// Explicit instantiation for all the error codes.
+// If we add more error code, we need to add their values on this list.
+// Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier
+// to see that the list is complete.
+template Status MakeErrorStringRvalueImpl<0>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<1>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<2>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<3>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<4>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<5>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<6>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<7>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<8>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<9>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<10>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<11>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<12>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<13>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<14>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<15>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<16>(std::string&&, SourceLocation);
+#endif  // SWIG
+
 }  // namespace status_internal
 
 bool IsAborted(const Status& status) {
diff --git a/absl/status/status.h b/absl/status/status.h
index 3103e79..f86065a 100644
--- a/absl/status/status.h
+++ b/absl/status/status.h
@@ -469,8 +469,7 @@
   // Same as above but for rvalue string.
   // Note: using a template to disambiguate the case of matching string_view and
   // string&& (e.g. char*) as a template lowers the priority of the overload.
-  template <typename String,
-            typename = std::enable_if_t<std::is_same_v<String, std::string>>>
+  template <typename String, typename = status_internal::EnableIfString<String>>
   Status(absl::StatusCode code, String&& msg,
          absl::SourceLocation loc = SourceLocation::current());
 #endif  // SWIG
@@ -890,45 +889,176 @@
 // These convenience functions create an `absl::Status` object with an error
 // code as indicated by the associated function name, using the error message
 // passed in `message`.
+// Note: using a template for the rvalue message overload to disambiguate the
+// case of matching string_view and string&& (e.g. char*) as a template lowers
+// the priority of the overload.
+
+// AbortedError
 Status AbortedError(absl::string_view message,
                     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status AbortedError(String&& message,
+                    absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// AlreadyExistsError
 Status AlreadyExistsError(absl::string_view message,
                           absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status AlreadyExistsError(String&& message,
+                          absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// CancelledError
 Status CancelledError(absl::string_view message,
                       absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status CancelledError(String&& message,
+                      absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// DataLossError
 Status DataLossError(absl::string_view message,
                      absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status DataLossError(String&& message,
+                     absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// DeadlineExceededError
 Status DeadlineExceededError(
     absl::string_view message,
     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status DeadlineExceededError(
+    String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// FailedPreconditionError
 Status FailedPreconditionError(
     absl::string_view message,
     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status FailedPreconditionError(
+    String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// InternalError
 Status InternalError(absl::string_view message,
                      absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status InternalError(String&& message,
+                     absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// InvalidArgumentError
 Status InvalidArgumentError(
     absl::string_view message,
     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status InvalidArgumentError(
+    String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// NotFoundError
 Status NotFoundError(absl::string_view message,
                      absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status NotFoundError(String&& message,
+                     absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// OutOfRangeError
 Status OutOfRangeError(absl::string_view message,
                        absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status OutOfRangeError(String&& message,
+                       absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// PermissionDeniedError
 Status PermissionDeniedError(
     absl::string_view message,
     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status PermissionDeniedError(
+    String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// ResourceExhaustedError
 Status ResourceExhaustedError(
     absl::string_view message,
     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status ResourceExhaustedError(
+    String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// UnauthenticatedError
 Status UnauthenticatedError(
     absl::string_view message,
     absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnauthenticatedError(
+    String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// UnavailableError
 Status UnavailableError(absl::string_view message,
                         absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnavailableError(String&& message,
+                        absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// UnimplementedError
 Status UnimplementedError(absl::string_view message,
                           absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnimplementedError(String&& message,
+                          absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
+// UnknownError
 Status UnknownError(absl::string_view message,
                     absl::SourceLocation loc = SourceLocation::current());
 
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnknownError(String&& message,
+                    absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
+
 // ErrnoToStatusCode()
 //
 // Returns the StatusCode for `error_number`, which should be an `errno` value.
@@ -1143,110 +1273,339 @@
 namespace status_internal {
 // We use an int in the template parameter to shorten mangled names.
 template <int error_code>
-Status MakeErrorImpl(string_view message, SourceLocation loc);
+Status MakeErrorStringViewImpl(string_view message, SourceLocation loc);
 // Make the instantiations extern to reduce bloat on callers.
 #ifndef SWIG
-extern template Status MakeErrorImpl<0>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<1>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<2>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<3>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<4>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<5>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<6>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<7>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<8>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<9>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<10>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<11>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<12>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<13>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<14>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<15>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<16>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<0>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<1>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<2>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<3>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<4>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<5>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<6>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<7>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<8>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<9>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<10>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<11>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<12>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<13>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<14>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<15>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<16>(string_view, SourceLocation);
 #endif  // SWIG
 
 template <StatusCode error_code>
-Status MakeError(string_view message, SourceLocation loc) {
-  Status out = MakeErrorImpl<static_cast<int>(error_code)>(message, loc);
+Status MakeErrorFromStringView(string_view message, SourceLocation loc) {
+  Status out =
+      MakeErrorStringViewImpl<static_cast<int>(error_code)>(message, loc);
   // -Wassume warning complains about potential side effects of `ok()`, so use a
   // local to avoid that.
   [[maybe_unused]] bool ok = out.ok();
   ABSL_ASSUME(!ok);
   return out;
 }
+
+// Same as above, but for rvalue std::string.
+#ifndef SWIG
+// We use an int in the template parameter to shorten mangled names.
+template <int error_code>
+Status MakeErrorStringRvalueImpl(std::string&& message, SourceLocation loc);
+// Make the instantiations extern to reduce bloat on callers.
+extern template Status MakeErrorStringRvalueImpl<0>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<1>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<2>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<3>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<4>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<5>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<6>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<7>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<8>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<9>(std::string&&,
+                                                    SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<10>(std::string&&,
+                                                     SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<11>(std::string&&,
+                                                     SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<12>(std::string&&,
+                                                     SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<13>(std::string&&,
+                                                     SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<14>(std::string&&,
+                                                     SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<15>(std::string&&,
+                                                     SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<16>(std::string&&,
+                                                     SourceLocation);
+
+template <StatusCode error_code, typename String>
+Status MakeErrorFromStringRvalue(String&& message, SourceLocation loc) {
+  static_assert(std::is_same_v<String&&, std::string&&>,
+                "`message` should be std::string&&");
+  Status out = MakeErrorStringRvalueImpl<static_cast<int>(error_code)>(
+      std::forward<String>(message), loc);
+  // -Wassume warning complains about potential side effects of `ok()`, so use a
+  // local to avoid that.
+  [[maybe_unused]] bool ok = out.ok();
+  ABSL_ASSUME(!ok);
+  return out;
+}
+#endif  // SWIG
+
 }  // namespace status_internal
 
 // Inline implementations to give the compiler static knowledge about the
 // objects.
+
+// AbortedError
 inline Status AbortedError(absl::string_view message,
                            absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kAborted>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kAborted>(message,
+                                                                        loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status AbortedError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kAborted>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// AlreadyExistsError
 inline Status AlreadyExistsError(absl::string_view message,
                                  absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kAlreadyExists>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kAlreadyExists>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status AlreadyExistsError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kAlreadyExists>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// CancelledError
 inline Status CancelledError(absl::string_view message,
                              absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kCancelled>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kCancelled>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status CancelledError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kCancelled>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// DataLossError
 inline Status DataLossError(absl::string_view message,
                             absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kDataLoss>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kDataLoss>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status DataLossError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kDataLoss>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// DeadlineExceededError
 inline Status DeadlineExceededError(absl::string_view message,
                                     absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kDeadlineExceeded>(message,
-                                                                   loc);
+  return status_internal::MakeErrorFromStringView<
+      StatusCode::kDeadlineExceeded>(message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status DeadlineExceededError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<
+      StatusCode::kDeadlineExceeded>(std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// FailedPreconditionError
 inline Status FailedPreconditionError(absl::string_view message,
                                       absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kFailedPrecondition>(message,
-                                                                     loc);
+  return status_internal::MakeErrorFromStringView<
+      StatusCode::kFailedPrecondition>(message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status FailedPreconditionError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<
+      StatusCode::kFailedPrecondition>(std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// InternalError
 inline Status InternalError(absl::string_view message,
                             absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kInternal>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kInternal>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status InternalError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kInternal>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// InvalidArgumentError
 inline Status InvalidArgumentError(absl::string_view message,
                                    absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kInvalidArgument>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kInvalidArgument>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status InvalidArgumentError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<
+      StatusCode::kInvalidArgument>(std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// NotFoundError
 inline Status NotFoundError(absl::string_view message,
                             absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kNotFound>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kNotFound>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status NotFoundError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kNotFound>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// OutOfRangeError
 inline Status OutOfRangeError(absl::string_view message,
                               absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kOutOfRange>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kOutOfRange>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status OutOfRangeError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kOutOfRange>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// PermissionDeniedError
 inline Status PermissionDeniedError(absl::string_view message,
                                     absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kPermissionDenied>(message,
-                                                                   loc);
+  return status_internal::MakeErrorFromStringView<
+      StatusCode::kPermissionDenied>(message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status PermissionDeniedError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<
+      StatusCode::kPermissionDenied>(std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// ResourceExhaustedError
 inline Status ResourceExhaustedError(absl::string_view message,
                                      absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kResourceExhausted>(message,
-                                                                    loc);
+  return status_internal::MakeErrorFromStringView<
+      StatusCode::kResourceExhausted>(message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status ResourceExhaustedError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<
+      StatusCode::kResourceExhausted>(std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// UnauthenticatedError
 inline Status UnauthenticatedError(absl::string_view message,
                                    absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kUnauthenticated>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kUnauthenticated>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnauthenticatedError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<
+      StatusCode::kUnauthenticated>(std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// UnavailableError
 inline Status UnavailableError(absl::string_view message,
                                absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kUnavailable>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kUnavailable>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnavailableError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnavailable>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// UnimplementedError
 inline Status UnimplementedError(absl::string_view message,
                                  absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kUnimplemented>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kUnimplemented>(
+      message, loc);
 }
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnimplementedError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnimplemented>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
+// UnknownError
 inline Status UnknownError(absl::string_view message,
                            absl::SourceLocation loc) {
-  return status_internal::MakeError<StatusCode::kUnknown>(message, loc);
+  return status_internal::MakeErrorFromStringView<StatusCode::kUnknown>(message,
+                                                                        loc);
 }
 
+#ifndef SWIG
+template <typename String, typename>
+Status UnknownError(String&& message, absl::SourceLocation loc) {
+  return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnknown>(
+      std::forward<String>(message), loc);
+}
+#endif  // SWIG
+
 ABSL_NAMESPACE_END
 }  // namespace absl
 
diff --git a/absl/status/status_benchmark.cc b/absl/status/status_benchmark.cc
index 0404db1..b001e63 100644
--- a/absl/status/status_benchmark.cc
+++ b/absl/status/status_benchmark.cc
@@ -57,4 +57,14 @@
 }
 BENCHMARK(BM_LongMessageRValue);
 
+void BM_LongMessageRValueConvenienceFn(benchmark::State& state) {
+  for (auto _ : state) {
+    std::string msg(100, 'X');
+    benchmark::DoNotOptimize(msg);
+    absl::Status s = absl::InvalidArgumentError(std::move(msg));
+    benchmark::DoNotOptimize(s);
+  }
+}
+BENCHMARK(BM_LongMessageRValueConvenienceFn);
+
 }  // namespace
diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc
index ddf0be0..c4679d6 100644
--- a/absl/status/status_test.cc
+++ b/absl/status/status_test.cc
@@ -19,6 +19,7 @@
 #include <array>
 #include <cstddef>
 #include <sstream>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -46,41 +47,82 @@
 }
 
 // This structure holds the details for testing a single error code,
-// its creator, and its classifier.
+// its creator, its rvalue creator, and its classifier.
 struct ErrorTest {
   absl::StatusCode code;
   using Creator = absl::Status (*)(absl::string_view, absl::SourceLocation);
-  using Classifier = bool (*)(const absl::Status&);
   Creator creator;
+  using CreatorRValue = absl::Status (*)(std::string&&, absl::SourceLocation);
+  CreatorRValue creator_rvalue;
+  using Classifier = bool (*)(const absl::Status&);
   Classifier classifier;
 };
 
 constexpr ErrorTest kErrorTests[]{
-    {absl::StatusCode::kCancelled, absl::CancelledError, absl::IsCancelled},
-    {absl::StatusCode::kUnknown, absl::UnknownError, absl::IsUnknown},
-    {absl::StatusCode::kInvalidArgument, absl::InvalidArgumentError,
-     absl::IsInvalidArgument},
-    {absl::StatusCode::kDeadlineExceeded, absl::DeadlineExceededError,
-     absl::IsDeadlineExceeded},
-    {absl::StatusCode::kNotFound, absl::NotFoundError, absl::IsNotFound},
-    {absl::StatusCode::kAlreadyExists, absl::AlreadyExistsError,
-     absl::IsAlreadyExists},
-    {absl::StatusCode::kPermissionDenied, absl::PermissionDeniedError,
-     absl::IsPermissionDenied},
-    {absl::StatusCode::kResourceExhausted, absl::ResourceExhaustedError,
-     absl::IsResourceExhausted},
-    {absl::StatusCode::kFailedPrecondition, absl::FailedPreconditionError,
-     absl::IsFailedPrecondition},
-    {absl::StatusCode::kAborted, absl::AbortedError, absl::IsAborted},
-    {absl::StatusCode::kOutOfRange, absl::OutOfRangeError, absl::IsOutOfRange},
-    {absl::StatusCode::kUnimplemented, absl::UnimplementedError,
-     absl::IsUnimplemented},
-    {absl::StatusCode::kInternal, absl::InternalError, absl::IsInternal},
-    {absl::StatusCode::kUnavailable, absl::UnavailableError,
-     absl::IsUnavailable},
-    {absl::StatusCode::kDataLoss, absl::DataLossError, absl::IsDataLoss},
-    {absl::StatusCode::kUnauthenticated, absl::UnauthenticatedError,
-     absl::IsUnauthenticated},
+    {absl::StatusCode::kCancelled,           //
+     absl::CancelledError,                   //
+     absl::CancelledError,                   //
+     absl::IsCancelled},                     //
+    {absl::StatusCode::kUnknown,             //
+     absl::UnknownError,                     //
+     absl::UnknownError,                     //
+     absl::IsUnknown},                       //
+    {absl::StatusCode::kInvalidArgument,     //
+     absl::InvalidArgumentError,             //
+     absl::InvalidArgumentError,             //
+     absl::IsInvalidArgument},               //
+    {absl::StatusCode::kDeadlineExceeded,    //
+     absl::DeadlineExceededError,            //
+     absl::DeadlineExceededError,            //
+     absl::IsDeadlineExceeded},              //
+    {absl::StatusCode::kNotFound,            //
+     absl::NotFoundError,                    //
+     absl::NotFoundError,                    //
+     absl::IsNotFound},                      //
+    {absl::StatusCode::kAlreadyExists,       //
+     absl::AlreadyExistsError,               //
+     absl::AlreadyExistsError,               //
+     absl::IsAlreadyExists},                 //
+    {absl::StatusCode::kPermissionDenied,    //
+     absl::PermissionDeniedError,            //
+     absl::PermissionDeniedError,            //
+     absl::IsPermissionDenied},              //
+    {absl::StatusCode::kResourceExhausted,   //
+     absl::ResourceExhaustedError,           //
+     absl::ResourceExhaustedError,           //
+     absl::IsResourceExhausted},             //
+    {absl::StatusCode::kFailedPrecondition,  //
+     absl::FailedPreconditionError,          //
+     absl::FailedPreconditionError,          //
+     absl::IsFailedPrecondition},            //
+    {absl::StatusCode::kAborted,             //
+     absl::AbortedError,                     //
+     absl::AbortedError,                     //
+     absl::IsAborted},                       //
+    {absl::StatusCode::kOutOfRange,          //
+     absl::OutOfRangeError,                  //
+     absl::OutOfRangeError,                  //
+     absl::IsOutOfRange},                    //
+    {absl::StatusCode::kUnimplemented,       //
+     absl::UnimplementedError,               //
+     absl::UnimplementedError,               //
+     absl::IsUnimplemented},                 //
+    {absl::StatusCode::kInternal,            //
+     absl::InternalError,                    //
+     absl::InternalError,                    //
+     absl::IsInternal},                      //
+    {absl::StatusCode::kUnavailable,         //
+     absl::UnavailableError,                 //
+     absl::UnavailableError,                 //
+     absl::IsUnavailable},                   //
+    {absl::StatusCode::kDataLoss,            //
+     absl::DataLossError,                    //
+     absl::DataLossError,                    //
+     absl::IsDataLoss},                      //
+    {absl::StatusCode::kUnauthenticated,     //
+     absl::UnauthenticatedError,             //
+     absl::UnauthenticatedError,             //
+     absl::IsUnauthenticated},               //
 };
 
 TEST(Status, CreateAndClassify) {
@@ -96,9 +138,16 @@
     EXPECT_EQ(test.code, status.code());
     EXPECT_EQ(message, status.message());
 
+    // Testing the rvalue creator.
+    absl::Status status_rvalue = test.creator_rvalue(
+        std::string(message), absl::SourceLocation::current());
+    EXPECT_EQ(test.code, status_rvalue.code());
+    EXPECT_EQ(message, status_rvalue.message());
+
     // Ensure that the classifier returns true for a status produced by the
     // creator.
     EXPECT_TRUE(test.classifier(status));
+    EXPECT_TRUE(test.classifier(status_rvalue));
 
     // Ensure that the classifier returns false for status with a different
     // code.
@@ -111,6 +160,37 @@
   }
 }
 
+// Test that status convenience functions can be called with a string literal.
+// Doing so to make sure it's not ambiguous between the string_view and string&&
+// overloads.
+TEST(Status, StringLiteralCreation) {
+  EXPECT_EQ(absl::AbortedError("msg").code(), absl::StatusCode::kAborted);
+  EXPECT_EQ(absl::AlreadyExistsError("msg").code(),
+            absl::StatusCode::kAlreadyExists);
+  EXPECT_EQ(absl::CancelledError("msg").code(), absl::StatusCode::kCancelled);
+  EXPECT_EQ(absl::DataLossError("msg").code(), absl::StatusCode::kDataLoss);
+  EXPECT_EQ(absl::DeadlineExceededError("msg").code(),
+            absl::StatusCode::kDeadlineExceeded);
+  EXPECT_EQ(absl::FailedPreconditionError("msg").code(),
+            absl::StatusCode::kFailedPrecondition);
+  EXPECT_EQ(absl::InternalError("msg").code(), absl::StatusCode::kInternal);
+  EXPECT_EQ(absl::InvalidArgumentError("msg").code(),
+            absl::StatusCode::kInvalidArgument);
+  EXPECT_EQ(absl::NotFoundError("msg").code(), absl::StatusCode::kNotFound);
+  EXPECT_EQ(absl::OutOfRangeError("msg").code(), absl::StatusCode::kOutOfRange);
+  EXPECT_EQ(absl::PermissionDeniedError("msg").code(),
+            absl::StatusCode::kPermissionDenied);
+  EXPECT_EQ(absl::ResourceExhaustedError("msg").code(),
+            absl::StatusCode::kResourceExhausted);
+  EXPECT_EQ(absl::UnauthenticatedError("msg").code(),
+            absl::StatusCode::kUnauthenticated);
+  EXPECT_EQ(absl::UnavailableError("msg").code(),
+            absl::StatusCode::kUnavailable);
+  EXPECT_EQ(absl::UnimplementedError("msg").code(),
+            absl::StatusCode::kUnimplemented);
+  EXPECT_EQ(absl::UnknownError("msg").code(), absl::StatusCode::kUnknown);
+}
+
 TEST(Status, DefaultConstructor) {
   absl::Status status;
   EXPECT_TRUE(status.ok());
@@ -340,37 +420,37 @@
 
 TEST(Status, OstreamOperator) {
   absl::Status status(absl::StatusCode::kInternal, "fail");
-  { std::stringstream stream;
+  {
+    std::stringstream stream;
     stream << status;
-    EXPECT_THAT(stream.str(),
-                AllOf(HasSubstr("INTERNAL: fail"),
-                      HasSubstr("status_test.cc:")));
+    EXPECT_THAT(stream.str(), AllOf(HasSubstr("INTERNAL: fail"),
+                                    HasSubstr("status_test.cc:")));
   }
   status.SetPayload("foo", absl::Cord("bar"));
-  { std::stringstream stream;
+  {
+    std::stringstream stream;
     stream << status;
     EXPECT_THAT(stream.str(),
                 AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
                       HasSubstr("status_test.cc:")));
   }
   status.SetPayload("bar", absl::Cord("\377"));
-  { std::stringstream stream;
+  {
+    std::stringstream stream;
     stream << status;
-    EXPECT_THAT(stream.str(),
-                AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
-                      HasSubstr("[bar='\\xff']"),
-                      HasSubstr("status_test.cc:")));
+    EXPECT_THAT(
+        stream.str(),
+        AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+              HasSubstr("[bar='\\xff']"), HasSubstr("status_test.cc:")));
   }
 }
 
 TEST(Status, AbslStringify) {
   absl::Status status(absl::StatusCode::kInternal, "fail");
   EXPECT_THAT(absl::StrCat(status),
-              AllOf(HasSubstr("INTERNAL: fail"),
-                    HasSubstr("status_test.cc:")));
+              AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("status_test.cc:")));
   EXPECT_THAT(absl::StrFormat("%v", status),
-              AllOf(HasSubstr("INTERNAL: fail"),
-                    HasSubstr("status_test.cc:")));
+              AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("status_test.cc:")));
   EXPECT_EQ(absl::StrCat(status), absl::StrFormat("%v", status));
   status.SetPayload("foo", absl::Cord("bar"));
   EXPECT_THAT(absl::StrCat(status),
@@ -379,8 +459,7 @@
   status.SetPayload("bar", absl::Cord("\377"));
   EXPECT_THAT(absl::StrCat(status),
               AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
-                    HasSubstr("[bar='\\xff']"),
-                    HasSubstr("status_test.cc:")));
+                    HasSubstr("[bar='\\xff']"), HasSubstr("status_test.cc:")));
 }
 
 TEST(Status, OstreamEqStringify) {
@@ -867,8 +946,7 @@
   {
     // Status that ignores source location.
     absl::Status status_ignores_source_location[] = {
-        absl::Status(),
-        absl::Status(absl::StatusCode::kInternal, "")};
+        absl::Status(), absl::Status(absl::StatusCode::kInternal, "")};
     for (absl::Status& s : status_ignores_source_location) {
       for (int i = 0; i < max_iter; ++i) {
         s.AddSourceLocation(absl::SourceLocation::current());
@@ -967,27 +1045,27 @@
 
   s.SetPayload("bar", absl::Cord("\377"));
 
-  EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithEverything),
-              AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
-                    HasSubstr("[bar='\\xff']"),
-                    HasSubstr(source_location_string),
-                    HasSubstr(source_location_stack)));
-  EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload |
-                         absl::StatusToStringMode::kWithSourceLocation),
-              AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
-                    HasSubstr("[bar='\\xff']"),
-                    HasSubstr(source_location_string),
-                    HasSubstr(source_location_stack)));
-  EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithSourceLocation),
-              AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")),
-                    Not(HasSubstr("[bar='\\xff']")),
-                    HasSubstr(source_location_string),
-                    HasSubstr(source_location_stack)));
-  EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload),
-              AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
-                    HasSubstr("[bar='\\xff']"),
-                    Not(HasSubstr(source_location_string)),
-                    Not(HasSubstr(source_location_stack))));
+  EXPECT_THAT(
+      s.ToString(absl::StatusToStringMode::kWithEverything),
+      AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+            HasSubstr("[bar='\\xff']"), HasSubstr(source_location_string),
+            HasSubstr(source_location_stack)));
+  EXPECT_THAT(
+      s.ToString(absl::StatusToStringMode::kWithPayload |
+                 absl::StatusToStringMode::kWithSourceLocation),
+      AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+            HasSubstr("[bar='\\xff']"), HasSubstr(source_location_string),
+            HasSubstr(source_location_stack)));
+  EXPECT_THAT(
+      s.ToString(absl::StatusToStringMode::kWithSourceLocation),
+      AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")),
+            Not(HasSubstr("[bar='\\xff']")), HasSubstr(source_location_string),
+            HasSubstr(source_location_stack)));
+  EXPECT_THAT(
+      s.ToString(absl::StatusToStringMode::kWithPayload),
+      AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+            HasSubstr("[bar='\\xff']"), Not(HasSubstr(source_location_string)),
+            Not(HasSubstr(source_location_stack))));
 }
 
 TEST(Status, StackTracePayloadOverflow) {
diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc
index 51f3750..8a95049 100644
--- a/absl/status/statusor_test.cc
+++ b/absl/status/statusor_test.cc
@@ -118,8 +118,8 @@
 }
 
 TEST(StatusOr, ElementType) {
-  static_assert(std::is_same<absl::StatusOr<int>::value_type, int>(), "");
-  static_assert(std::is_same<absl::StatusOr<char>::value_type, char>(), "");
+  static_assert(std::is_same<absl::StatusOr<int>::value_type, int>());
+  static_assert(std::is_same<absl::StatusOr<char>::value_type, char>());
 }
 
 TEST(StatusOr, TestMoveOnlyInitialization) {
@@ -1393,7 +1393,7 @@
 
 TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) {
   using EvilType = std::vector<std::unique_ptr<int>>;
-  static_assert(std::is_copy_constructible_v<EvilType>, "");
+  static_assert(std::is_copy_constructible_v<EvilType>);
   std::vector<::absl::StatusOr<EvilType>> v(5);
   v.reserve(v.capacity() + 10);
   v.resize(v.capacity() + 10);
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index 7e80259..fad5d97 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -177,7 +177,7 @@
 // Additionally, the API provides iterator utilities to iterate through Cord
 // data via chunks or character bytes.
 //
-class Cord {
+class ABSL_ATTRIBUTE_TRIVIAL_ABI Cord {
  private:
   template <typename T>
   using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>, int>;
@@ -915,10 +915,10 @@
   // to the representation.
   //
   // InlineRep holds either a tree pointer, or an array of kMaxInline bytes.
-  class InlineRep {
+  class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineRep {
    public:
     static constexpr unsigned char kMaxInline = cord_internal::kMaxInline;
-    static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), "");
+    static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*));
 
     constexpr InlineRep() : data_() {}
     explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {}
@@ -1124,7 +1124,6 @@
   void CopyToArrayImpl(char* absl_nonnull dst) const;
 };
 
-
 // allow a Cord to be logged
 extern std::ostream& operator<<(std::ostream& out, const Cord& cord);
 
@@ -1285,7 +1284,7 @@
 
 inline cord_internal::CordRepFlat* absl_nonnull
 Cord::InlineRep::MakeFlatWithExtraCapacity(size_t extra) {
-  static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
+  static_assert(cord_internal::kMinFlatLength >= sizeof(data_));
   size_t len = data_.inline_size();
   auto* result = CordRepFlat::New(len + extra);
   result->length = len;
diff --git a/absl/strings/cord_buffer.h b/absl/strings/cord_buffer.h
index fc806bb..a2d1b32 100644
--- a/absl/strings/cord_buffer.h
+++ b/absl/strings/cord_buffer.h
@@ -290,7 +290,7 @@
 
  private:
   // Make sure we don't accidentally over promise.
-  static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize, "");
+  static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize);
 
   // Assume the cost of an 'uprounded' allocation to CeilPow2(size) versus
   // the cost of allocating at least 1 extra flat <= 4KB:
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index cf65453..7a2c936 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -277,9 +277,9 @@
 
 TEST(CordRepFlat, AllFlatCapacities) {
   // Explicitly and redundantly assert built-in min/max limits
-  static_assert(absl::cord_internal::kFlatOverhead < 32, "");
-  static_assert(absl::cord_internal::kMinFlatSize == 32, "");
-  static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10, "");
+  static_assert(absl::cord_internal::kFlatOverhead < 32);
+  static_assert(absl::cord_internal::kMinFlatSize == 32);
+  static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10);
   EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(FLAT), 32);
   EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(MAX_FLAT_TAG), 256 << 10);
 
@@ -2364,35 +2364,30 @@
 }
 
 TEST_P(CordTest, CordChunkIteratorTraits) {
-  static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>, "");
-  static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>, "");
+  static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>);
+  static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>);
 
   // Move semantics to satisfy swappable via std::swap
-  static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>, "");
-  static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>, "");
+  static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>);
+  static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>);
 
   static_assert(
       std::is_same_v<
           std::iterator_traits<absl::Cord::ChunkIterator>::iterator_category,
-          std::input_iterator_tag>,
-      "");
+          std::input_iterator_tag>);
   static_assert(std::is_same_v<
-                    std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
-                    absl::string_view>,
-                "");
+                std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
+                absl::string_view>);
   static_assert(
       std::is_same_v<
           std::iterator_traits<absl::Cord::ChunkIterator>::difference_type,
-          ptrdiff_t>,
-      "");
+          ptrdiff_t>);
   static_assert(
       std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::pointer,
-                     const absl::string_view*>,
-      "");
+                     const absl::string_view*>);
   static_assert(
       std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::reference,
-                     absl::string_view>,
-      "");
+                     absl::string_view>);
 }
 
 static void VerifyChunkIterator(const absl::Cord& cord,
@@ -2551,35 +2546,29 @@
 }
 
 TEST_P(CordTest, CharIteratorTraits) {
-  static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>, "");
-  static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>, "");
+  static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>);
+  static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>);
 
   // Move semantics to satisfy swappable via std::swap
-  static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>, "");
-  static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>, "");
+  static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>);
+  static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>);
 
   static_assert(
       std::is_same_v<
           std::iterator_traits<absl::Cord::CharIterator>::iterator_category,
-          std::input_iterator_tag>,
-      "");
+          std::input_iterator_tag>);
   static_assert(
       std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::value_type,
-                     char>,
-      "");
-  static_assert(
-      std::is_same_v<
-          std::iterator_traits<absl::Cord::CharIterator>::difference_type,
-          ptrdiff_t>,
-      "");
+                     char>);
+  static_assert(std::is_same_v<
+                std::iterator_traits<absl::Cord::CharIterator>::difference_type,
+                ptrdiff_t>);
   static_assert(
       std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::pointer,
-                     const char*>,
-      "");
+                     const char*>);
   static_assert(
       std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::reference,
-                     const char&>,
-      "");
+                     const char&>);
 }
 
 static void VerifyCharIterator(const absl::Cord& cord) {
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h
index 98dc4b5..650f514 100644
--- a/absl/strings/internal/cord_internal.h
+++ b/absl/strings/internal/cord_internal.h
@@ -35,8 +35,11 @@
 #include "absl/strings/string_view.h"
 
 // We can only add poisoning if we can detect consteval executions.
-#if defined(ABSL_HAVE_CONSTANT_EVALUATED) && \
-    (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
+//
+// TODO(b/548049702): attempt to turn this back on. It's disabled because asan
+// interacts poorly with trivial ABIs (http://b/546331925).
+#if 0 && defined(ABSL_HAVE_CONSTANT_EVALUATED) && \
+    (defined(ABSL_HAVE_ADDRESS_SANITIZER) ||      \
      defined(ABSL_HAVE_MEMORY_SANITIZER))
 #define ABSL_INTERNAL_CORD_HAVE_SANITIZER 1
 #endif
@@ -465,8 +468,8 @@
 
 // Assert that the `cordz_info` pointer value perfectly overlaps the last half
 // of `data` and can hold a pointer value.
-static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1, "");
-static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t), "");
+static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1);
+static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t));
 
 // LittleEndianByte() creates a little endian representation of 'value', i.e.:
 // a little endian value where the first byte in the host's representation
@@ -479,7 +482,7 @@
 #endif
 }
 
-class InlineData {
+class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineData {
  public:
   // DefaultInitType forces the use of the default initialization constructor.
   enum DefaultInitType { kDefaultInit };
@@ -516,7 +519,7 @@
   // value. Creates an inlined SSO value if `rep` is null, otherwise
   // creates a tree instance value.
   constexpr InlineData(absl::string_view sv, CordRep* rep) noexcept
-      : rep_(rep ? Rep(rep) : Rep(sv)) {
+      : rep_(rep != nullptr ? Rep(rep) : Rep(sv)) {
     poison();
   }
 
@@ -833,7 +836,7 @@
   Rep rep_;
 };
 
-static_assert(sizeof(InlineData) == kMaxInline + 1, "");
+static_assert(sizeof(InlineData) == kMaxInline + 1);
 
 #ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
 
diff --git a/absl/strings/internal/cord_rep_btree.cc b/absl/strings/internal/cord_rep_btree.cc
index 92e6450..d816522 100644
--- a/absl/strings/internal/cord_rep_btree.cc
+++ b/absl/strings/internal/cord_rep_btree.cc
@@ -278,7 +278,7 @@
         return tree;
       case CordRepBtree::kCopied:
         CordRep::Unref(tree);
-        ABSL_FALLTHROUGH_INTENDED;
+        [[fallthrough]];
       case CordRepBtree::kSelf:
         return result.tree;
     }
diff --git a/absl/strings/internal/cord_rep_btree.h b/absl/strings/internal/cord_rep_btree.h
index ab259af..852cc17 100644
--- a/absl/strings/internal/cord_rep_btree.h
+++ b/absl/strings/internal/cord_rep_btree.h
@@ -865,16 +865,16 @@
       tree = tree->Edge(kBack)->btree();
       if (!tree->refcount.IsOne()) return {};
       n2 = tree;
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case 2:
       tree = tree->Edge(kBack)->btree();
       if (!tree->refcount.IsOne()) return {};
       n1 = tree;
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case 1:
       tree = tree->Edge(kBack)->btree();
       if (!tree->refcount.IsOne()) return {};
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case 0:
       CordRep* edge = tree->Edge(kBack);
       if (!edge->refcount.IsOne()) return {};
@@ -887,13 +887,13 @@
       switch (height) {
         case 3:
           n3->length += delta;
-          ABSL_FALLTHROUGH_INTENDED;
+          [[fallthrough]];
         case 2:
           n2->length += delta;
-          ABSL_FALLTHROUGH_INTENDED;
+          [[fallthrough]];
         case 1:
           n1->length += delta;
-          ABSL_FALLTHROUGH_INTENDED;
+          [[fallthrough]];
         case 0:
           tree->length += delta;
           return span;
diff --git a/absl/strings/internal/cord_rep_flat.h b/absl/strings/internal/cord_rep_flat.h
index 27c4b21..3cdeca6 100644
--- a/absl/strings/internal/cord_rep_flat.h
+++ b/absl/strings/internal/cord_rep_flat.h
@@ -69,9 +69,8 @@
                    ((512 / 8) + ((8192 - 512) / 64)) * 4096;
 }
 
-static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT, "");
-static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG,
-              "");
+static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT);
+static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG);
 
 // RoundUp logically performs `((n + m - 1) / m) * m` to round up to the nearest
 // multiple of `m`, optimized for the invariant that `m` is a power of 2.
diff --git a/absl/strings/internal/cordz_sample_token_test.cc b/absl/strings/internal/cordz_sample_token_test.cc
index 22ef21c..ccb28d0 100644
--- a/absl/strings/internal/cordz_sample_token_test.cc
+++ b/absl/strings/internal/cordz_sample_token_test.cc
@@ -44,33 +44,27 @@
 auto constexpr kTrackCordMethod = CordzUpdateTracker::kConstructorString;
 
 TEST(CordzSampleTokenTest, IteratorTraits) {
-  static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>, "");
-  static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>, "");
-  static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>, "");
-  static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>, "");
+  static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>);
+  static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>);
+  static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>);
+  static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>);
   static_assert(
       std::is_same_v<
           std::iterator_traits<CordzSampleToken::Iterator>::iterator_category,
-          std::input_iterator_tag>,
-      "");
-  static_assert(
-      std::is_same_v<
-          std::iterator_traits<CordzSampleToken::Iterator>::value_type,
-          const CordzInfo&>,
-      "");
+          std::input_iterator_tag>);
+  static_assert(std::is_same_v<
+                std::iterator_traits<CordzSampleToken::Iterator>::value_type,
+                const CordzInfo&>);
   static_assert(
       std::is_same_v<
           std::iterator_traits<CordzSampleToken::Iterator>::difference_type,
-          ptrdiff_t>,
-      "");
+          ptrdiff_t>);
   static_assert(
       std::is_same_v<std::iterator_traits<CordzSampleToken::Iterator>::pointer,
-                     const CordzInfo*>,
-      "");
+                     const CordzInfo*>);
   static_assert(std::is_same_v<
-                    std::iterator_traits<CordzSampleToken::Iterator>::reference,
-                    const CordzInfo&>,
-                "");
+                std::iterator_traits<CordzSampleToken::Iterator>::reference,
+                const CordzInfo&>);
 }
 
 TEST(CordzSampleTokenTest, IteratorEmpty) {
diff --git a/absl/strings/internal/ostringstream_test.cc b/absl/strings/internal/ostringstream_test.cc
index ef3ad57..c0f88c1 100644
--- a/absl/strings/internal/ostringstream_test.cc
+++ b/absl/strings/internal/ostringstream_test.cc
@@ -27,8 +27,7 @@
 
 TEST(OStringStream, IsOStream) {
   static_assert(
-      std::is_base_of<std::ostream, absl::strings_internal::OStringStream>(),
-      "");
+      std::is_base_of<std::ostream, absl::strings_internal::OStringStream>());
 }
 
 TEST(OStringStream, ConstructNullptr) {
@@ -83,8 +82,8 @@
   absl::strings_internal::OStringStream strm(&s1);
   const absl::strings_internal::OStringStream& c_strm(strm);
 
-  static_assert(std::is_same<decltype(strm.str()), std::string*>(), "");
-  static_assert(std::is_same<decltype(c_strm.str()), const std::string*>(), "");
+  static_assert(std::is_same<decltype(strm.str()), std::string*>());
+  static_assert(std::is_same<decltype(c_strm.str()), const std::string*>());
 
   EXPECT_EQ(&s1, strm.str());
   EXPECT_EQ(&s1, c_strm.str());
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index 0687b4e..2125be3 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -82,7 +82,7 @@
   // Supports unsigned integral types and uint128.
   template <typename T>
   void PrintAsOct(T v) {
-    static_assert(!IsSigned<T>::value, "");
+    static_assert(!IsSigned<T>::value);
     char *p = storage_ + sizeof(storage_);
     do {
       *--p = static_cast<char>('0' + (static_cast<size_t>(v) & 7));
@@ -96,7 +96,7 @@
   // Supports all integral types.
   template <typename T>
   void PrintAsDec(T v) {
-    static_assert(std::is_integral_v<T>, "");
+    static_assert(std::is_integral_v<T>);
     start_ = storage_;
     size_ = static_cast<size_t>(numbers_internal::FastIntToBuffer(v, storage_) -
                                 storage_);
@@ -136,7 +136,7 @@
   // Supports unsigned integral types and uint128.
   template <typename T>
   void PrintAsHexLower(T v) {
-    static_assert(!IsSigned<T>::value, "");
+    static_assert(!IsSigned<T>::value);
     char *p = storage_ + sizeof(storage_);
 
     do {
@@ -158,7 +158,7 @@
   // Supports unsigned integral types and uint128.
   template <typename T>
   void PrintAsHexUpper(T v) {
-    static_assert(!IsSigned<T>::value, "");
+    static_assert(!IsSigned<T>::value);
     char *p = storage_ + sizeof(storage_);
 
     // kHexTable is only lowercase, so do it manually for uppercase.
diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc
index 87e23b5..689fa5c 100644
--- a/absl/strings/internal/str_format/bind.cc
+++ b/absl/strings/internal/str_format/bind.cc
@@ -251,7 +251,7 @@
     errno = sink.error();
     return -1;
   }
-  if (sink.count() > static_cast<size_t>(std::numeric_limits<int>::max())) {
+  if (sink.count() > size_t{std::numeric_limits<int>::max()}) {
     errno = EFBIG;
     return -1;
   }
@@ -267,6 +267,10 @@
   }
   size_t total = sink.total_written();
   if (size) output[std::min(total, size - 1)] = 0;
+  if (total > size_t{std::numeric_limits<int>::max()}) {
+    errno = EFBIG;
+    return -1;
+  }
   return static_cast<int>(total);
 }
 
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index 173284c..0e0b262 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -290,7 +290,7 @@
   FormatConversionChar conversion_char() const {
     // Keep this field first in the struct . It generates better code when
     // accessing it when ConversionSpec is passed by value in registers.
-    static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, "");
+    static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0);
     return conv_;
   }
 
diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc
index f69b8ef..137e159 100644
--- a/absl/strings/internal/str_format/float_conversion.cc
+++ b/absl/strings/internal/str_format/float_conversion.cc
@@ -149,8 +149,7 @@
     assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent);
     static_assert(
         StackArray::kMaxCapacity >=
-            ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent),
-        "");
+            ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent));
 
     StackArray::RunWithCapacity(
         ChunksNeeded(exp),
@@ -267,8 +266,7 @@
     const int margin = Limits::digits + 128;
     assert(-exp >= Limits::min_exponent - margin);
     static_assert(StackArray::kMaxCapacity >=
-                      ChunksNeeded(margin - Limits::min_exponent),
-                  "");
+                      ChunksNeeded(margin - Limits::min_exponent));
     StackArray::RunWithCapacity(
         ChunksNeeded(exp), [=](absl::Span<uint32_t> input) {
           f(FractionalDigitGenerator(input, v, exp));
@@ -1178,8 +1176,7 @@
 struct Decomposed {
   using MantissaType =
       std::conditional_t<std::is_same_v<long double, Float>, uint128, uint64_t>;
-  static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8,
-                "");
+  static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8);
   MantissaType mantissa;
   int exponent;
 };
diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h
index bda084b..4e29790 100644
--- a/absl/strings/internal/str_split_internal.h
+++ b/absl/strings/internal/str_split_internal.h
@@ -244,16 +244,14 @@
 
 template <typename StringType, typename First, typename Second>
 using ShouldUseLifetimeBoundForPair =
-    std::integral_constant<bool,
-                           std::is_same_v<StringType, std::string> &&
-                               (std::is_same_v<First, absl::string_view> ||
-                                std::is_same_v<Second, absl::string_view>)>;
+    std::bool_constant<std::is_same_v<StringType, std::string> &&
+                       (std::is_same_v<First, absl::string_view> ||
+                        std::is_same_v<Second, absl::string_view>)>;
 
 template <typename StringType, typename ElementType, std::size_t Size>
 using ShouldUseLifetimeBoundForArray =
-    std::integral_constant<bool,
-                           std::is_same_v<StringType, std::string> &&
-                               std::is_same_v<ElementType, absl::string_view>>;
+    std::bool_constant<std::is_same_v<StringType, std::string> &&
+                       std::is_same_v<ElementType, absl::string_view>>;
 
 // This class implements the range that is returned by absl::StrSplit(). This
 // class has templated conversion operators that allow it to be implicitly
diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc
index 479c07e..924c912 100644
--- a/absl/strings/numbers.cc
+++ b/absl/strings/numbers.cc
@@ -1124,15 +1124,15 @@
     case -4:
       out[2] = '0';
       ++out;
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case -3:
       out[2] = '0';
       ++out;
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case -2:
       out[2] = '0';
       ++out;
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case -1:
       out += 2;
       memcpy(out, &digits[0], 6);
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h
index d02fe20..6ec289e 100644
--- a/absl/strings/str_format.h
+++ b/absl/strings/str_format.h
@@ -309,9 +309,8 @@
 //     ... error case ...
 //   }
 
-#if defined(__cpp_nontype_template_parameter_auto)
-// If C++17 is available, an 'extended' format is also allowed that can specify
-// multiple conversion characters per format argument, using a combination of
+// An 'extended' format is also allowed that can specify multiple conversion
+// characters per format argument, using a combination of
 // `absl::FormatConversionCharSet` enum values (logically a set union)
 //  via the `|` operator. (Single character-based arguments are still accepted,
 // but cannot be combined). Some common conversions also have predefined enum
@@ -333,11 +332,6 @@
 template <auto... Conv>
 using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat<
     absl::str_format_internal::ToFormatConversionCharSet(Conv)...>;
-#else
-template <char... Conv>
-using ParsedFormat = str_format_internal::ExtendedParsedFormat<
-    absl::str_format_internal::ToFormatConversionCharSet(Conv)...>;
-#endif  // defined(__cpp_nontype_template_parameter_auto)
 
 // StrFormat()
 //
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc
index 019284b..a0db73f 100644
--- a/absl/strings/str_format_test.cc
+++ b/absl/strings/str_format_test.cc
@@ -524,6 +524,19 @@
   EXPECT_EQ(buffer[0], '\0');
 }
 
+TEST_F(FormatEntryPointTest, SNPrintFTooLarge) {
+  // Formatting more than INT_MAX bytes cannot be represented in the int return
+  // value, so the call reports an error via errno rather than returning a
+  // truncated (and possibly negative) count, matching FPrintF. A zero size
+  // means nothing is written to the buffer.
+  char buffer[16];
+  int width = 2000000000;
+  errno = 0;
+  int result = SNPrintF(buffer, 0, "%*d %*d", width, 0, width, 0);
+  EXPECT_LT(result, 0);
+  EXPECT_EQ(errno, EFBIG);
+}
+
 TEST_F(FormatEntryPointTest, SNPrintFWithV) {
   char buffer[16];
   int result =
diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc
index 57aa87e..8155311 100644
--- a/absl/strings/str_split_test.cc
+++ b/absl/strings/str_split_test.cc
@@ -48,31 +48,23 @@
 using ::testing::UnorderedElementsAre;
 
 TEST(Split, TraitsTest) {
-  static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value,
-                "");
+  static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value);
   static_assert(
-      !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value, "");
+      !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value);
   static_assert(absl::strings_internal::SplitterIsConvertibleTo<
-                    std::vector<std::string>>::value,
-                "");
-  static_assert(
-      !absl::strings_internal::SplitterIsConvertibleTo<std::vector<int>>::value,
-      "");
-  static_assert(absl::strings_internal::SplitterIsConvertibleTo<
-                    std::vector<absl::string_view>>::value,
-                "");
-  static_assert(absl::strings_internal::SplitterIsConvertibleTo<
-                    std::map<std::string, std::string>>::value,
-                "");
-  static_assert(absl::strings_internal::SplitterIsConvertibleTo<
-                    std::map<absl::string_view, absl::string_view>>::value,
-                "");
+                std::vector<std::string>>::value);
   static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
-                    std::map<int, std::string>>::value,
-                "");
+                std::vector<int>>::value);
+  static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+                std::vector<absl::string_view>>::value);
+  static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+                std::map<std::string, std::string>>::value);
+  static_assert(absl::strings_internal::SplitterIsConvertibleTo<
+                std::map<absl::string_view, absl::string_view>>::value);
   static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
-                    std::map<std::string, int>>::value,
-                "");
+                std::map<int, std::string>>::value);
+  static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
+                std::map<std::string, int>>::value);
 }
 
 // This tests the overall split API, which is made up of the absl::StrSplit()
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index 942fc03..57740ef 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -49,6 +49,7 @@
     }),
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
+        "//absl/algorithm:container",
         "//absl/base",
         "//absl/base:base_internal",
         "//absl/base:config",
@@ -69,9 +70,7 @@
         "@do_not_use_for_gloop_visibility_only//gloop/thread:__subpackages__",
     ],
     deps = [
-        "//absl/base",
         "//absl/base:config",
-        "//absl/base:core_headers",
         "//absl/base:raw_logging_internal",
         "//absl/time",
     ],
@@ -85,8 +84,6 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":kernel_timeout_internal",
-        "//absl/base:config",
-        "//absl/random",
         "//absl/time",
         "@googletest//:gtest",
         "@googletest//:gtest_main",
@@ -215,7 +212,9 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":graphcycles_internal",
+        "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/container:flat_hash_set",
         "//absl/log",
         "//absl/log:check",
         "@googletest//:gtest",
@@ -264,12 +263,10 @@
     deps = [
         ":synchronization",
         ":thread_pool",
-        "//absl/base",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/log",
         "//absl/log:check",
-        "//absl/memory",
         "//absl/random",
         "//absl/time",
         "@googletest//:gtest",
@@ -284,7 +281,6 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":synchronization",
-        "//absl/base:config",
         "@googletest//:gtest",
         "@googletest//:gtest_main",
     ],
@@ -302,8 +298,8 @@
         ":synchronization",
         ":thread_pool",
         "//absl/base",
-        "//absl/base:config",
         "//absl/base:no_destructor",
+        "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
     ],
     alwayslink = 1,
@@ -348,9 +344,11 @@
         "@do_not_use_for_gloop_visibility_only//gloop/base:__subpackages__",
     ],
     deps = [
+        ":kernel_timeout_internal",
         ":synchronization",
         "//absl/base",
         "//absl/base:config",
+        "//absl/base:core_headers",
         "//absl/strings",
         "//absl/time",
         "@googletest//:gtest",
@@ -386,7 +384,6 @@
         ":kernel_timeout_internal",
         ":synchronization",
         ":thread_pool",
-        "//absl/base:config",
         "//absl/random",
         "//absl/time",
         "@googletest//:gtest",
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index 9c4a0b1..2805000 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -157,6 +157,7 @@
   DEPS
     absl::check
     absl::core_headers
+    absl::flat_hash_map
     absl::graphcycles_internal
     absl::log
     GTest::gmock_main
diff --git a/absl/synchronization/barrier.cc b/absl/synchronization/barrier.cc
index f5dad22..e5cbdc6 100644
--- a/absl/synchronization/barrier.cc
+++ b/absl/synchronization/barrier.cc
@@ -14,6 +14,7 @@
 
 #include "absl/synchronization/barrier.h"
 
+#include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/synchronization/mutex.h"
 
diff --git a/absl/synchronization/barrier_test.cc b/absl/synchronization/barrier_test.cc
index 2aed272..2cfb57c 100644
--- a/absl/synchronization/barrier_test.cc
+++ b/absl/synchronization/barrier_test.cc
@@ -20,7 +20,7 @@
 #include "gtest/gtest.h"
 #include "absl/synchronization/mutex.h"
 #include "absl/time/clock.h"
-
+#include "absl/time/time.h"
 
 TEST(Barrier, SanityTest) {
   constexpr int kNumThreads = 10;
diff --git a/absl/synchronization/blocking_counter.cc b/absl/synchronization/blocking_counter.cc
index 9468469..d38b260 100644
--- a/absl/synchronization/blocking_counter.cc
+++ b/absl/synchronization/blocking_counter.cc
@@ -16,8 +16,10 @@
 
 #include <atomic>
 
+#include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/tracing.h"
+#include "absl/synchronization/mutex.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/synchronization/blocking_counter.h b/absl/synchronization/blocking_counter.h
index d0504a1..46c010b 100644
--- a/absl/synchronization/blocking_counter.h
+++ b/absl/synchronization/blocking_counter.h
@@ -91,7 +91,7 @@
 
  private:
   // Convenience helper to reduce verbosity at call sites.
-  static inline constexpr base_internal::ObjectKind TraceObjectKind() {
+  static constexpr base_internal::ObjectKind TraceObjectKind() {
     return base_internal::ObjectKind::kBlockingCounter;
   }
 
diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc
index e10d3bc..d7168da 100644
--- a/absl/synchronization/internal/create_thread_identity.cc
+++ b/absl/synchronization/internal/create_thread_identity.cc
@@ -12,18 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <stdint.h>
-
-#include <new>
+#include "absl/base/internal/low_level_alloc.h"  // IWYU pragma: keep
 
 // This file is a no-op if the required LowLevelAlloc support is missing.
-#include "absl/base/internal/low_level_alloc.h"
-#include "absl/synchronization/internal/waiter.h"
 #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
 
-#include <string.h>
+#include <atomic>
+#include <cstdint>
+#include <new>
 
 #include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/scheduling_mode.h"
 #include "absl/base/internal/spinlock.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/synchronization/internal/per_thread_sem.h"
diff --git a/absl/synchronization/internal/futex_waiter.cc b/absl/synchronization/internal/futex_waiter.cc
index 8945c17..d7666d9 100644
--- a/absl/synchronization/internal/futex_waiter.cc
+++ b/absl/synchronization/internal/futex_waiter.cc
@@ -17,15 +17,14 @@
 #ifdef ABSL_INTERNAL_HAVE_FUTEX_WAITER
 
 #include <atomic>
-#include <cstdint>
 #include <cerrno>
+#include <cstdint>
 
 #include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
 #include "absl/base/optimization.h"
-#include "absl/synchronization/internal/kernel_timeout.h"
 #include "absl/synchronization/internal/futex.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc
index 3f8bb3a..25b51ff 100644
--- a/absl/synchronization/internal/graphcycles.cc
+++ b/absl/synchronization/internal/graphcycles.cc
@@ -28,22 +28,25 @@
 // (2) When a new edge (x->y) is inserted, do nothing if rank[x] < rank[y].
 // (3) Otherwise: adjust ranks in the neighborhood of x and y.
 
-#include <cstddef>
-#include <iterator>
-
-#include "absl/base/attributes.h"
+#include "absl/base/internal/low_level_alloc.h"  // IWYU pragma: keep
 // This file is a no-op if the required LowLevelAlloc support is missing.
-#include "absl/base/internal/low_level_alloc.h"
 #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
 
 #include <algorithm>
 #include <array>
 #include <cinttypes>
+#include <cstddef>
+#include <cstdint>
 #include <limits>
 
+#include "absl/algorithm/container.h"
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
 #include "absl/base/internal/hide_ptr.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/scheduling_mode.h"
 #include "absl/base/internal/spinlock.h"
+#include "absl/base/macros.h"
 #include "absl/synchronization/internal/graphcycles.h"
 
 // Do not use STL.   This module does not use standard memory allocation.
@@ -625,7 +628,7 @@
   };
   ByRank cmp;
   cmp.nodes = &nodes;
-  std::sort(delta->begin(), delta->end(), cmp);
+  absl::c_sort(*delta, cmp);
 }
 
 static void MoveToList(GraphCycles::Rep* r, Vec<int32_t>* src,
diff --git a/absl/synchronization/internal/graphcycles.h b/absl/synchronization/internal/graphcycles.h
index 08f304b..da06504 100644
--- a/absl/synchronization/internal/graphcycles.h
+++ b/absl/synchronization/internal/graphcycles.h
@@ -80,20 +80,20 @@
   // Attempt to insert an edge from source_node to dest_node.  If the
   // edge would introduce a cycle, return false without making any
   // changes. Otherwise add the edge and return true.
-  bool InsertEdge(GraphId source_node, GraphId dest_node);
+  bool InsertEdge(GraphId idx, GraphId idy);
 
   // Remove any edge that exists from source_node to dest_node.
-  void RemoveEdge(GraphId source_node, GraphId dest_node);
+  void RemoveEdge(GraphId x, GraphId y);
 
   // Return whether node exists in the graph.
   bool HasNode(GraphId node);
 
   // Return whether there is an edge directly from source_node to dest_node.
-  bool HasEdge(GraphId source_node, GraphId dest_node) const;
+  bool HasEdge(GraphId x, GraphId y) const;
 
   // Return whether dest_node is reachable from source_node
   // by following edges.
-  bool IsReachable(GraphId source_node, GraphId dest_node) const;
+  bool IsReachable(GraphId x, GraphId y) const;
 
   // Find a path from "source" to "dest".  If such a path exists,
   // place the nodes on the path in the array path[], and return
@@ -107,7 +107,7 @@
   // source and destination node if they are identical; therefore, the
   // return value is at most one greater than the number of nodes in
   // the graph.
-  int FindPath(GraphId source, GraphId dest, int max_path_len,
+  int FindPath(GraphId idx, GraphId idy, int max_path_len,
                GraphId path[]) const;
 
   // Update the stack trace recorded for id with the current stack
@@ -143,4 +143,4 @@
 ABSL_NAMESPACE_END
 }  // namespace absl
 
-#endif
+#endif  // ABSL_SYNCHRONIZATION_INTERNAL_GRAPHCYCLES_H_
diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc
index 4f1a485..9e44a58 100644
--- a/absl/synchronization/internal/graphcycles_test.cc
+++ b/absl/synchronization/internal/graphcycles_test.cc
@@ -16,6 +16,7 @@
 
 #include <climits>
 #include <cstdint>
+#include <cstdio>
 #include <iterator>
 #include <map>
 #include <random>
@@ -24,7 +25,9 @@
 #include <vector>
 
 #include "gtest/gtest.h"
+#include "absl/base/config.h"
 #include "absl/base/macros.h"
+#include "absl/container/flat_hash_set.h"
 #include "absl/log/check.h"
 #include "absl/log/log.h"
 
@@ -51,8 +54,8 @@
 }
 
 // Return whether "to" is reachable from "from".
-static bool IsReachable(Edges *edges, int from, int to,
-                        std::unordered_set<int> *seen) {
+static bool IsReachable(Edges* edges, int from, int to,
+                        absl::flat_hash_set<int>* seen) {
   seen->insert(from);     // we are investigating "from"; don't do it again
   if (from == to) return true;
   for (const auto &edge : *edges) {
@@ -94,7 +97,7 @@
   LOG(INFO) << "Transitive closure";
   for (int a : *nodes) {
     for (int b : *nodes) {
-      std::unordered_set<int> seen;
+      absl::flat_hash_set<int> seen;
       if (IsReachable(edges, a, b, &seen)) {
         LOG(INFO) << a << " " << b;
       }
@@ -118,7 +121,7 @@
 
 static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id,
                                    GraphCycles *gc) {
-  std::unordered_set<int> seen;
+  absl::flat_hash_set<int> seen;
   for (const auto &a : *nodes) {
     for (const auto &b : *nodes) {
       seen.clear();
@@ -227,7 +230,7 @@
       break;
 
     case 1:    // Remove a node
-      if (nodes.size() > 0) {
+      if (!nodes.empty()) {
         int node_index = RandomNode(&rng, &nodes);
         int node = nodes[node_index];
         nodes[node_index] = nodes.back();
@@ -248,7 +251,7 @@
       break;
 
     case 2:   // Add an edge
-      if (nodes.size() > 0) {
+      if (!nodes.empty()) {
         int from = RandomNode(&rng, &nodes);
         int to = RandomNode(&rng, &nodes);
         if (EdgeIndex(&edges, nodes[from], nodes[to]) == -1) {
@@ -258,7 +261,7 @@
             new_edge.to = nodes[to];
             edges.push_back(new_edge);
           } else {
-            std::unordered_set<int> seen;
+            absl::flat_hash_set<int> seen;
             ASSERT_TRUE(IsReachable(&edges, nodes[to], nodes[from], &seen))
                 << "Edge " << nodes[to] << "->" << nodes[from];
           }
@@ -267,7 +270,7 @@
       break;
 
     case 3:    // Remove an edge
-      if (edges.size() > 0) {
+      if (!edges.empty()) {
         int i = RandomEdge(&rng, &edges);
         int from = edges[i].from;
         int to = edges[i].to;
@@ -280,13 +283,13 @@
       break;
 
     case 4:   // Check a path
-      if (nodes.size() > 0) {
+      if (!nodes.empty()) {
         int from = RandomNode(&rng, &nodes);
         int to = RandomNode(&rng, &nodes);
         GraphId path[2*kMaxNodes];
         int path_len = graph_cycles.FindPath(id[nodes[from]], id[nodes[to]],
                                              std::size(path), path);
-        std::unordered_set<int> seen;
+        absl::flat_hash_set<int> seen;
         bool reachable = IsReachable(&edges, nodes[from], nodes[to], &seen);
         bool gc_reachable =
             graph_cycles.IsReachable(Get(id, nodes[from]), Get(id, nodes[to]));
diff --git a/absl/synchronization/internal/kernel_timeout.cc b/absl/synchronization/internal/kernel_timeout.cc
index 252397a..cce8bf7 100644
--- a/absl/synchronization/internal/kernel_timeout.cc
+++ b/absl/synchronization/internal/kernel_timeout.cc
@@ -21,14 +21,12 @@
 #include <algorithm>
 #include <chrono>  // NOLINT(build/c++11)
 #include <cstdint>
-#include <cstdlib>
-#include <cstring>
 #include <ctime>
 #include <limits>
 
-#include "absl/base/attributes.h"
-#include "absl/base/call_once.h"
 #include "absl/base/config.h"
+#include "absl/base/internal/raw_logging.h"
+#include "absl/time/clock.h"
 #include "absl/time/time.h"
 
 namespace absl {
diff --git a/absl/synchronization/internal/kernel_timeout_test.cc b/absl/synchronization/internal/kernel_timeout_test.cc
index 811246c..baa2e0f 100644
--- a/absl/synchronization/internal/kernel_timeout_test.cc
+++ b/absl/synchronization/internal/kernel_timeout_test.cc
@@ -14,15 +14,14 @@
 
 #include "absl/synchronization/internal/kernel_timeout.h"
 
-#include <ctime>
+#include <algorithm>
 #include <chrono>  // NOLINT(build/c++11)
+#include <cstdint>
 #include <limits>
 
-#include "absl/base/config.h"
-#include "absl/random/random.h"
+#include "gtest/gtest.h"
 #include "absl/time/clock.h"
 #include "absl/time/time.h"
-#include "gtest/gtest.h"
 
 #if 0  // All supported platforms currently have steady clocks.
 #define ABSL_INTERNAL_KERNEL_TIMEOUT_SUPPORTS_STEADY_CLOCK 0
diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc
index c9b8dc1..8ba2a20 100644
--- a/absl/synchronization/internal/per_thread_sem.cc
+++ b/absl/synchronization/internal/per_thread_sem.cc
@@ -12,16 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// This file is a no-op if the required LowLevelAlloc support is missing.
-#include "absl/base/internal/low_level_alloc.h"
-#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
+#include "absl/base/internal/low_level_alloc.h"  // IWYU pragma: keep
 
-#include "absl/synchronization/internal/per_thread_sem.h"
+// This file is a no-op if the required LowLevelAlloc support is missing.
+#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
 
 #include <atomic>
 
 #include "absl/base/attributes.h"
+#include "absl/base/config.h"
 #include "absl/base/internal/thread_identity.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
+#include "absl/synchronization/internal/per_thread_sem.h"
 #include "absl/synchronization/internal/waiter.h"
 
 namespace absl {
diff --git a/absl/synchronization/internal/per_thread_sem_test.cc b/absl/synchronization/internal/per_thread_sem_test.cc
index 46f903a..4c5ca69 100644
--- a/absl/synchronization/internal/per_thread_sem_test.cc
+++ b/absl/synchronization/internal/per_thread_sem_test.cc
@@ -14,19 +14,25 @@
 
 #include "absl/synchronization/internal/per_thread_sem.h"
 
+#include <algorithm>
 #include <atomic>
 #include <condition_variable>  // NOLINT(build/c++11)
+#include <cstdint>
+#include <cstdio>
 #include <functional>
 #include <limits>
-#include <mutex>               // NOLINT(build/c++11)
+#include <mutex>  // NOLINT(build/c++11)
 #include <string>
-#include <thread>              // NOLINT(build/c++11)
+#include <thread>  // NOLINT(build/c++11)
 
 #include "gtest/gtest.h"
+#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/cycleclock.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/strings/str_cat.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
 #include "absl/time/clock.h"
 #include "absl/time/time.h"
 
diff --git a/absl/synchronization/internal/pthread_waiter.cc b/absl/synchronization/internal/pthread_waiter.cc
index eead9de..5b27d0f 100644
--- a/absl/synchronization/internal/pthread_waiter.cc
+++ b/absl/synchronization/internal/pthread_waiter.cc
@@ -25,7 +25,6 @@
 
 #include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
 #include "absl/base/optimization.h"
 #include "absl/synchronization/internal/kernel_timeout.h"
 
@@ -59,12 +58,12 @@
 }  // namespace
 
 PthreadWaiter::PthreadWaiter() : waiter_count_(0), wakeup_count_(0) {
-  const int err = pthread_mutex_init(&mu_, 0);
+  const int err = pthread_mutex_init(&mu_, nullptr);
   if (err != 0) {
     ABSL_RAW_LOG(FATAL, "pthread_mutex_init failed: %d", err);
   }
 
-  const int err2 = pthread_cond_init(&cv_, 0);
+  const int err2 = pthread_cond_init(&cv_, nullptr);
   if (err2 != 0) {
     ABSL_RAW_LOG(FATAL, "pthread_cond_init failed: %d", err2);
   }
diff --git a/absl/synchronization/internal/sem_waiter.cc b/absl/synchronization/internal/sem_waiter.cc
index 2119290..50f5960 100644
--- a/absl/synchronization/internal/sem_waiter.cc
+++ b/absl/synchronization/internal/sem_waiter.cc
@@ -20,13 +20,10 @@
 
 #include <atomic>
 #include <cassert>
-#include <cstdint>
 #include <cerrno>
 
 #include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
-#include "absl/base/optimization.h"
 #include "absl/synchronization/internal/kernel_timeout.h"
 
 namespace absl {
diff --git a/absl/synchronization/internal/stdcpp_waiter.cc b/absl/synchronization/internal/stdcpp_waiter.cc
index 607d683..c9368d5 100644
--- a/absl/synchronization/internal/stdcpp_waiter.cc
+++ b/absl/synchronization/internal/stdcpp_waiter.cc
@@ -16,14 +16,10 @@
 
 #ifdef ABSL_INTERNAL_HAVE_STDCPP_WAITER
 
-#include <chrono>  // NOLINT(build/c++11)
 #include <condition_variable>  // NOLINT(build/c++11)
 #include <mutex>  // NOLINT(build/c++11)
 
 #include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
-#include "absl/base/optimization.h"
 #include "absl/synchronization/internal/kernel_timeout.h"
 
 namespace absl {
diff --git a/absl/synchronization/internal/waiter_base.cc b/absl/synchronization/internal/waiter_base.cc
index e9797f8..011de18 100644
--- a/absl/synchronization/internal/waiter_base.cc
+++ b/absl/synchronization/internal/waiter_base.cc
@@ -14,6 +14,9 @@
 
 #include "absl/synchronization/internal/waiter_base.h"
 
+#include <atomic>
+#include <cassert>
+
 #include "absl/base/config.h"
 #include "absl/base/internal/thread_identity.h"
 
diff --git a/absl/synchronization/internal/waiter_test.cc b/absl/synchronization/internal/waiter_test.cc
index 80a6985..44f0d6f 100644
--- a/absl/synchronization/internal/waiter_test.cc
+++ b/absl/synchronization/internal/waiter_test.cc
@@ -18,7 +18,7 @@
 #include <iostream>
 #include <ostream>
 
-#include "absl/base/config.h"
+#include "gtest/gtest.h"
 #include "absl/random/random.h"
 #include "absl/synchronization/internal/create_thread_identity.h"
 #include "absl/synchronization/internal/futex_waiter.h"
@@ -27,10 +27,8 @@
 #include "absl/synchronization/internal/sem_waiter.h"
 #include "absl/synchronization/internal/stdcpp_waiter.h"
 #include "absl/synchronization/internal/thread_pool.h"
-#include "absl/synchronization/internal/win32_waiter.h"
 #include "absl/time/clock.h"
 #include "absl/time/time.h"
-#include "gtest/gtest.h"
 
 // Test go/btm support by randomizing the value of clock_gettime() for
 // CLOCK_MONOTONIC. This works by overriding a weak symbol in glibc.
diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc
index 1c11431..a659bcf 100644
--- a/absl/synchronization/lifetime_test.cc
+++ b/absl/synchronization/lifetime_test.cc
@@ -14,7 +14,6 @@
 
 #include <cstdlib>
 #include <thread>  // NOLINT(build/c++11), Abseil test
-#include <type_traits>
 
 #include "absl/base/attributes.h"
 #include "absl/base/const_init.h"
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index 63414bb..cb982f6 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -28,7 +28,6 @@
 #endif
 
 #include <assert.h>
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,6 +36,7 @@
 #include <algorithm>
 #include <atomic>
 #include <cstddef>
+#include <cstdint>
 #include <cstdlib>
 #include <cstring>
 #include <thread>  // NOLINT(build/c++11)
@@ -49,16 +49,23 @@
 #include "absl/base/internal/cycleclock.h"
 #include "absl/base/internal/hide_ptr.h"
 #include "absl/base/internal/low_level_alloc.h"
+#include "absl/base/internal/low_level_scheduling.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/scheduling_mode.h"
 #include "absl/base/internal/spinlock.h"
 #include "absl/base/internal/sysinfo.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/base/internal/tsan_mutex_interface.h"
+#include "absl/base/macros.h"
 #include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
 #include "absl/debugging/stacktrace.h"
 #include "absl/debugging/symbolize.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
 #include "absl/synchronization/internal/graphcycles.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
 #include "absl/synchronization/internal/per_thread_sem.h"
+#include "absl/time/clock.h"
 #include "absl/time/time.h"
 
 using absl::base_internal::CurrentThreadIdentityIfPresent;
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index 03cce89..b81c595 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -964,7 +964,7 @@
 
   // Helper methods for storing, validating, and reading callback arguments.
   template <typename T>
-  inline void StoreCallback(T callback) {
+  void StoreCallback(T callback) {
     static_assert(
         sizeof(callback) <= sizeof(callback_),
         "An overlarge pointer was passed as a callback to Condition.");
@@ -972,7 +972,7 @@
   }
 
   template <typename T>
-  inline void ReadCallback(T* absl_nonnull callback) const {
+  void ReadCallback(T* absl_nonnull callback) const {
     std::memcpy(callback, callback_, sizeof(*callback));
   }
 
@@ -1188,7 +1188,7 @@
   ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
 }
 
-inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
+constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
 
 #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL)
 ABSL_ATTRIBUTE_ALWAYS_INLINE
diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc
index d2c6495..2df1d67 100644
--- a/absl/synchronization/mutex_benchmark.cc
+++ b/absl/synchronization/mutex_benchmark.cc
@@ -12,15 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <atomic>
 #include <cstdint>
+#include <limits>
 #include <mutex>  // NOLINT(build/c++11)
 #include <vector>
 
-#include "absl/base/config.h"
 #include "absl/base/internal/cycleclock.h"
+#include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/spinlock.h"
+#include "absl/base/internal/thread_identity.h"
 #include "absl/base/no_destructor.h"
 #include "absl/synchronization/blocking_counter.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
+#include "absl/synchronization/internal/per_thread_sem.h"
 #include "absl/synchronization/internal/thread_pool.h"
 #include "absl/synchronization/mutex.h"
 #include "benchmark/benchmark.h"
@@ -30,7 +35,7 @@
 void BM_Mutex(benchmark::State& state) {
   static absl::NoDestructor<absl::Mutex> mu;
   for (auto _ : state) {
-    absl::MutexLock lock(*mu.get());
+    absl::MutexLock lock(*mu);
   }
 }
 BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu();
@@ -38,7 +43,7 @@
 void BM_ReaderLock(benchmark::State& state) {
   static absl::NoDestructor<absl::Mutex> mu;
   for (auto _ : state) {
-    absl::ReaderMutexLock lock(*mu.get());
+    absl::ReaderMutexLock lock(*mu);
   }
 }
 BENCHMARK(BM_ReaderLock)->UseRealTime()->Threads(1)->ThreadPerCpu();
diff --git a/absl/synchronization/mutex_method_pointer_test.cc b/absl/synchronization/mutex_method_pointer_test.cc
index f4c82d2..420750b 100644
--- a/absl/synchronization/mutex_method_pointer_test.cc
+++ b/absl/synchronization/mutex_method_pointer_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/synchronization/mutex.h"
-
-#include <cstdlib>
 #include <string>
 
 #include "gtest/gtest.h"
-#include "absl/base/config.h"
+
+#ifdef _MSC_VER
+#include "absl/synchronization/mutex.h"
+#endif
 
 namespace {
 
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc
index 5663cf6..42e5eb9 100644
--- a/absl/synchronization/mutex_test.cc
+++ b/absl/synchronization/mutex_test.cc
@@ -24,6 +24,7 @@
 #include <functional>
 #include <memory>
 #include <mutex>  // NOLINT(build/c++11)
+#include <ostream>
 #include <random>
 #include <shared_mutex>  // NOLINT(build/c++14)
 #include <string>
@@ -32,12 +33,10 @@
 #include <vector>
 
 #include "gtest/gtest.h"
-#include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/internal/sysinfo.h"
+#include "absl/base/thread_annotations.h"
 #include "absl/log/check.h"
 #include "absl/log/log.h"
-#include "absl/memory/memory.h"
 #include "absl/random/random.h"
 #include "absl/synchronization/internal/create_thread_identity.h"
 #include "absl/synchronization/internal/thread_pool.h"
diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc
index a890c1b..63da068 100644
--- a/absl/synchronization/notification.cc
+++ b/absl/synchronization/notification.cc
@@ -16,8 +16,10 @@
 
 #include <atomic>
 
+#include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/tracing.h"
+#include "absl/base/optimization.h"
 #include "absl/synchronization/mutex.h"
 #include "absl/time/time.h"
 
diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h
index 12df31b..420b820 100644
--- a/absl/synchronization/notification.h
+++ b/absl/synchronization/notification.h
@@ -114,12 +114,11 @@
 
  private:
   // Convenience helper to reduce verbosity at call sites.
-  static inline constexpr base_internal::ObjectKind TraceObjectKind() {
+  static constexpr base_internal::ObjectKind TraceObjectKind() {
     return base_internal::ObjectKind::kNotification;
   }
 
-  static inline bool HasBeenNotifiedInternal(
-      const std::atomic<bool>* notified_yet) {
+  static bool HasBeenNotifiedInternal(const std::atomic<bool>* notified_yet) {
     return notified_yet->load(std::memory_order_acquire);
   }
 
diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc
index ac5dccd..ded80a5 100644
--- a/absl/synchronization/notification_test.cc
+++ b/absl/synchronization/notification_test.cc
@@ -23,6 +23,7 @@
 #include "absl/base/config.h"
 #include "absl/base/internal/tracing.h"
 #include "absl/synchronization/mutex.h"
+#include "absl/time/clock.h"
 #include "absl/time/time.h"
 
 namespace absl {
diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc
index f6d1682..fed0c30 100644
--- a/absl/time/civil_time_test.cc
+++ b/absl/time/civil_time_test.cc
@@ -296,33 +296,33 @@
 
 TEST(CivilTime, DisallowCrossAlignedDifference) {
   // Difference is allowed between types with the same alignment.
-  static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, "");
-  static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, "");
-  static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, "");
-  static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, "");
-  static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, "");
-  static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, "");
+  static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value);
+  static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value);
+  static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value);
+  static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value);
+  static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value);
+  static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value);
 
   // Difference is disallowed between types with different alignments.
-  static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, "");
-  static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, "");
-  static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, "");
-  static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, "");
-  static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, "");
+  static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value);
+  static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value);
+  static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value);
+  static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value);
+  static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value);
 
-  static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, "");
-  static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, "");
-  static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, "");
-  static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, "");
+  static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value);
+  static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value);
+  static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value);
+  static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value);
 
-  static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, "");
-  static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, "");
-  static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, "");
+  static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value);
+  static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value);
+  static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value);
 
-  static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, "");
-  static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, "");
+  static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value);
+  static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value);
 
-  static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, "");
+  static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value);
 }
 
 TEST(CivilTime, ValueSemantics) {
diff --git a/absl/time/duration.cc b/absl/time/duration.cc
index fb7c90a..ec92206 100644
--- a/absl/time/duration.cc
+++ b/absl/time/duration.cc
@@ -834,7 +834,7 @@
         default:
           break;
       }
-      ABSL_FALLTHROUGH_INTENDED;
+      [[fallthrough]];
     case 1:
       switch (**start) {
         case 's':
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc
index f56df40..d265dbf 100644
--- a/absl/time/duration_test.cc
+++ b/absl/time/duration_test.cc
@@ -228,12 +228,12 @@
   using std::chrono::nanoseconds;
   using std::chrono::seconds;
 
-  static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N)), "");
-  static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N)), "");
-  static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N)), "");
-  static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N)), "");
-  static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N)), "");
-  static_assert(absl::Hours(N) == absl::FromChrono(hours(N)), "");
+  static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N)));
+  static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N)));
+  static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N)));
+  static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N)));
+  static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N)));
+  static_assert(absl::Hours(N) == absl::FromChrono(hours(N)));
 }
 
 TEST(Duration, FromChrono) {
@@ -907,15 +907,15 @@
 }
 
 TEST(Duration, RelationalOperators) {
-#define TEST_REL_OPS(UNIT)               \
-  static_assert(UNIT(2) == UNIT(2), ""); \
-  static_assert(UNIT(1) != UNIT(2), ""); \
-  static_assert(UNIT(1) < UNIT(2), "");  \
-  static_assert(UNIT(3) > UNIT(2), "");  \
-  static_assert(UNIT(1) <= UNIT(2), ""); \
-  static_assert(UNIT(2) <= UNIT(2), ""); \
-  static_assert(UNIT(3) >= UNIT(2), ""); \
-  static_assert(UNIT(2) >= UNIT(2), "");
+#define TEST_REL_OPS(UNIT)           \
+  static_assert(UNIT(2) == UNIT(2)); \
+  static_assert(UNIT(1) != UNIT(2)); \
+  static_assert(UNIT(1) < UNIT(2));  \
+  static_assert(UNIT(3) > UNIT(2));  \
+  static_assert(UNIT(1) <= UNIT(2)); \
+  static_assert(UNIT(2) <= UNIT(2)); \
+  static_assert(UNIT(3) >= UNIT(2)); \
+  static_assert(UNIT(2) >= UNIT(2));
 
   TEST_REL_OPS(absl::Nanoseconds);
   TEST_REL_OPS(absl::Microseconds);
@@ -930,10 +930,10 @@
 #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 
 TEST(Duration, SpaceshipOperators) {
-#define TEST_REL_OPS(UNIT)                                               \
-  static_assert(UNIT(2) <=> UNIT(2) == std::strong_ordering::equal, ""); \
-  static_assert(UNIT(1) <=> UNIT(2) == std::strong_ordering::less, "");  \
-  static_assert(UNIT(3) <=> UNIT(2) == std::strong_ordering::greater, "");
+#define TEST_REL_OPS(UNIT)                                           \
+  static_assert(UNIT(2) <=> UNIT(2) == std::strong_ordering::equal); \
+  static_assert(UNIT(1) <=> UNIT(2) == std::strong_ordering::less);  \
+  static_assert(UNIT(3) <=> UNIT(2) == std::strong_ordering::greater);
 
   TEST_REL_OPS(absl::Nanoseconds);
   TEST_REL_OPS(absl::Microseconds);
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 35b1f0e..49f6dd6 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -194,46 +194,46 @@
   constexpr absl::Time t2 = absl::FromUnixNanos(1);
   constexpr absl::Time t3 = absl::FromUnixNanos(2);
 
-  static_assert(absl::UnixEpoch() == t1, "");
-  static_assert(t1 == t1, "");
-  static_assert(t2 == t2, "");
-  static_assert(t3 == t3, "");
+  static_assert(absl::UnixEpoch() == t1);
+  static_assert(t1 == t1);
+  static_assert(t2 == t2);
+  static_assert(t3 == t3);
 
-  static_assert(t1 < t2, "");
-  static_assert(t2 < t3, "");
-  static_assert(t1 < t3, "");
+  static_assert(t1 < t2);
+  static_assert(t2 < t3);
+  static_assert(t1 < t3);
 
-  static_assert(t1 <= t1, "");
-  static_assert(t1 <= t2, "");
-  static_assert(t2 <= t2, "");
-  static_assert(t2 <= t3, "");
-  static_assert(t3 <= t3, "");
-  static_assert(t1 <= t3, "");
+  static_assert(t1 <= t1);
+  static_assert(t1 <= t2);
+  static_assert(t2 <= t2);
+  static_assert(t2 <= t3);
+  static_assert(t3 <= t3);
+  static_assert(t1 <= t3);
 
-  static_assert(t2 > t1, "");
-  static_assert(t3 > t2, "");
-  static_assert(t3 > t1, "");
+  static_assert(t2 > t1);
+  static_assert(t3 > t2);
+  static_assert(t3 > t1);
 
-  static_assert(t2 >= t2, "");
-  static_assert(t2 >= t1, "");
-  static_assert(t3 >= t3, "");
-  static_assert(t3 >= t2, "");
-  static_assert(t1 >= t1, "");
-  static_assert(t3 >= t1, "");
+  static_assert(t2 >= t2);
+  static_assert(t2 >= t1);
+  static_assert(t3 >= t3);
+  static_assert(t3 >= t2);
+  static_assert(t1 >= t1);
+  static_assert(t3 >= t1);
 
 #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 
-  static_assert((t1 <=> t1) == std::strong_ordering::equal, "");
-  static_assert((t2 <=> t2) == std::strong_ordering::equal, "");
-  static_assert((t3 <=> t3) == std::strong_ordering::equal, "");
+  static_assert((t1 <=> t1) == std::strong_ordering::equal);
+  static_assert((t2 <=> t2) == std::strong_ordering::equal);
+  static_assert((t3 <=> t3) == std::strong_ordering::equal);
 
-  static_assert((t1 <=> t2) == std::strong_ordering::less, "");
-  static_assert((t2 <=> t3) == std::strong_ordering::less, "");
-  static_assert((t1 <=> t3) == std::strong_ordering::less, "");
+  static_assert((t1 <=> t2) == std::strong_ordering::less);
+  static_assert((t2 <=> t3) == std::strong_ordering::less);
+  static_assert((t1 <=> t3) == std::strong_ordering::less);
 
-  static_assert((t2 <=> t1) == std::strong_ordering::greater, "");
-  static_assert((t3 <=> t2) == std::strong_ordering::greater, "");
-  static_assert((t3 <=> t1) == std::strong_ordering::greater, "");
+  static_assert((t2 <=> t1) == std::strong_ordering::greater);
+  static_assert((t3 <=> t2) == std::strong_ordering::greater);
+  static_assert((t3 <=> t1) == std::strong_ordering::greater);
 
 #endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 }
@@ -242,17 +242,17 @@
   constexpr absl::Time ifuture = absl::InfiniteFuture();
   constexpr absl::Time ipast = absl::InfinitePast();
 
-  static_assert(ifuture == ifuture, "");
-  static_assert(ipast == ipast, "");
-  static_assert(ipast < ifuture, "");
-  static_assert(ifuture > ipast, "");
+  static_assert(ifuture == ifuture);
+  static_assert(ipast == ipast);
+  static_assert(ipast < ifuture);
+  static_assert(ifuture > ipast);
 
 #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 
-  static_assert((ifuture <=> ifuture) == std::strong_ordering::equal, "");
-  static_assert((ipast <=> ipast) == std::strong_ordering::equal, "");
-  static_assert((ipast <=> ifuture) == std::strong_ordering::less, "");
-  static_assert((ifuture <=> ipast) == std::strong_ordering::greater, "");
+  static_assert((ifuture <=> ifuture) == std::strong_ordering::equal);
+  static_assert((ipast <=> ipast) == std::strong_ordering::equal);
+  static_assert((ipast <=> ifuture) == std::strong_ordering::less);
+  static_assert((ifuture <=> ipast) == std::strong_ordering::greater);
 
 #endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 
@@ -268,15 +268,15 @@
   EXPECT_EQ(-absl::InfiniteDuration(), ipast - ipast);
 
   constexpr absl::Time t = absl::UnixEpoch();  // Any finite time.
-  static_assert(t < ifuture, "");
-  static_assert(t > ipast, "");
+  static_assert(t < ifuture);
+  static_assert(t > ipast);
 
 #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 
-  static_assert((t <=> ifuture) == std::strong_ordering::less, "");
-  static_assert((t <=> ipast) == std::strong_ordering::greater, "");
-  static_assert((ipast <=> t) == std::strong_ordering::less, "");
-  static_assert((ifuture <=> t) == std::strong_ordering::greater, "");
+  static_assert((t <=> ifuture) == std::strong_ordering::less);
+  static_assert((t <=> ipast) == std::strong_ordering::greater);
+  static_assert((ipast <=> t) == std::strong_ordering::less);
+  static_assert((ifuture <=> t) == std::strong_ordering::greater);
 
 #endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
 
diff --git a/absl/types/any_span.h b/absl/types/any_span.h
index 04e64dc..5c85892 100644
--- a/absl/types/any_span.h
+++ b/absl/types/any_span.h
@@ -390,7 +390,7 @@
   using difference_type = std::ptrdiff_t;
   using absl_internal_is_view = std::true_type;
 
-  static const size_type npos = static_cast<size_type>(-1);  // NOLINT
+  static constexpr size_type npos = static_cast<size_type>(-1);  // NOLINT
 
   using reference = T&;
   using const_reference = std::add_const_t<T>&;
@@ -893,9 +893,6 @@
 // Implementation details follow.
 //
 
-template <typename T>
-const typename AnySpan<T>::size_type AnySpan<T>::npos;
-
 // Iterator base class. Uses CRTP (Iter should be the child class). Constness of
 // the iterator is determined by the constness of Value.
 template <typename T>
diff --git a/absl/types/compare.h b/absl/types/compare.h
index be59d92..e6a2a57 100644
--- a/absl/types/compare.h
+++ b/absl/types/compare.h
@@ -23,7 +23,7 @@
 // Example:
 //   absl::weak_ordering compare(const std::string& a, const std::string& b);
 //
-// These are C++11 compatible versions of the C++20 corresponding types
+// These are C++17 compatible versions of the C++20 corresponding types
 // (`std::partial_ordering`, etc.) and are designed to be drop-in replacements
 // for code compliant with C++20.
 
@@ -110,71 +110,15 @@
 
 enum class ncmp : value_type { unordered = -127 };
 
-// Define macros to allow for creation or emulation of C++17 inline variables
-// based on whether the feature is supported. Note: we can't use
-// ABSL_INTERNAL_INLINE_CONSTEXPR here because the variables here are of
-// incomplete types so they need to be defined after the types are complete.
-#ifdef __cpp_inline_variables
-
-// A no-op expansion that can be followed by a semicolon at class level.
-#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "")
-
-#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static const type name
-
-#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
-  inline constexpr type type::name(init)
-
-#else  // __cpp_inline_variables
-
-#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \
-  ABSL_CONST_INIT static const T name
-
-// A no-op expansion that can be followed by a semicolon at class level.
-#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "")
-
-#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
-  template <typename T>                            \
-  const T compare_internal::type##_base<T>::name(init)
-
-#endif  // __cpp_inline_variables
-
-// These template base classes allow for defining the values of the constants
-// in the header file (for performance) without using inline variables (which
-// aren't available in C++11).
-template <typename T>
-struct partial_ordering_base {
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered);
-};
-
-template <typename T>
-struct weak_ordering_base {
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
-};
-
-template <typename T>
-struct strong_ordering_base {
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
-  ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
-};
-
 }  // namespace compare_internal
 
-class partial_ordering
-    : public compare_internal::partial_ordering_base<partial_ordering> {
+class partial_ordering {
   explicit constexpr partial_ordering(compare_internal::eq v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
   explicit constexpr partial_ordering(compare_internal::ord v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
   explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
-  friend struct compare_internal::partial_ordering_base<partial_ordering>;
 
   constexpr bool is_ordered() const noexcept {
     return value_ !=
@@ -182,10 +126,10 @@
   }
 
  public:
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered);
+  static const partial_ordering less;
+  static const partial_ordering equivalent;
+  static const partial_ordering greater;
+  static const partial_ordering unordered;
 
   // Comparisons
   friend constexpr bool operator==(partial_ordering v,
@@ -248,26 +192,25 @@
  private:
   compare_internal::value_type value_;
 };
-ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less);
-ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent,
-                         compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(partial_ordering, greater,
-                         compare_internal::ord::greater);
-ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered,
-                         compare_internal::ncmp::unordered);
+inline constexpr partial_ordering partial_ordering::less(
+    compare_internal::ord::less);
+inline constexpr partial_ordering partial_ordering::equivalent(
+    compare_internal::eq::equivalent);
+inline constexpr partial_ordering partial_ordering::greater(
+    compare_internal::ord::greater);
+inline constexpr partial_ordering partial_ordering::unordered(
+    compare_internal::ncmp::unordered);
 
-class weak_ordering
-    : public compare_internal::weak_ordering_base<weak_ordering> {
+class weak_ordering {
   explicit constexpr weak_ordering(compare_internal::eq v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
   explicit constexpr weak_ordering(compare_internal::ord v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
-  friend struct compare_internal::weak_ordering_base<weak_ordering>;
 
  public:
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater);
+  static const weak_ordering less;
+  static const weak_ordering equivalent;
+  static const weak_ordering greater;
 
   // Conversions
   constexpr operator partial_ordering() const noexcept {  // NOLINT
@@ -336,25 +279,23 @@
  private:
   compare_internal::value_type value_;
 };
-ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less);
-ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent,
-                         compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(weak_ordering, greater,
-                         compare_internal::ord::greater);
+inline constexpr weak_ordering weak_ordering::less(compare_internal::ord::less);
+inline constexpr weak_ordering weak_ordering::equivalent(
+    compare_internal::eq::equivalent);
+inline constexpr weak_ordering weak_ordering::greater(
+    compare_internal::ord::greater);
 
-class strong_ordering
-    : public compare_internal::strong_ordering_base<strong_ordering> {
+class strong_ordering {
   explicit constexpr strong_ordering(compare_internal::eq v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
   explicit constexpr strong_ordering(compare_internal::ord v) noexcept
       : value_(static_cast<compare_internal::value_type>(v)) {}
-  friend struct compare_internal::strong_ordering_base<strong_ordering>;
 
  public:
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent);
-  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater);
+  static const strong_ordering less;
+  static const strong_ordering equal;
+  static const strong_ordering equivalent;
+  static const strong_ordering greater;
 
   // Conversions
   constexpr operator partial_ordering() const noexcept {  // NOLINT
@@ -428,16 +369,14 @@
  private:
   compare_internal::value_type value_;
 };
-ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less);
-ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal);
-ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent,
-                         compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(strong_ordering, greater,
-                         compare_internal::ord::greater);
-
-#undef ABSL_COMPARE_INLINE_BASECLASS_DECL
-#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL
-#undef ABSL_COMPARE_INLINE_INIT
+inline constexpr strong_ordering strong_ordering::less(
+    compare_internal::ord::less);
+inline constexpr strong_ordering strong_ordering::equal(
+    compare_internal::eq::equal);
+inline constexpr strong_ordering strong_ordering::equivalent(
+    compare_internal::eq::equivalent);
+inline constexpr strong_ordering strong_ordering::greater(
+    compare_internal::ord::greater);
 
 #endif  // ABSL_USES_STD_ORDERING
 
@@ -479,7 +418,8 @@
 template <
     typename Compare, typename K, typename LK,
     std::enable_if_t<
-        !std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>,
+        !std::is_same_v<bool,
+                        std::invoke_result_t<Compare, const K&, const LK&>>,
         int> = 0>
 constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
                                                       const K& x, const LK& y) {
@@ -488,7 +428,8 @@
 template <
     typename Compare, typename K, typename LK,
     std::enable_if_t<
-        std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>,
+        std::is_same_v<bool,
+                       std::invoke_result_t<Compare, const K&, const LK&>>,
         int> = 0>
 constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
                                                       const K& x, const LK& y) {
diff --git a/absl/types/compare_test.cc b/absl/types/compare_test.cc
index 352c9f1..ae73eca 100644
--- a/absl/types/compare_test.cc
+++ b/absl/types/compare_test.cc
@@ -277,23 +277,21 @@
       absl::compare_internal::do_three_way_comparison(weak, 10, 5) > 0));
 }
 
-#ifdef __cpp_inline_variables
 TEST(Compare, StaticAsserts) {
-  static_assert(partial_ordering::less < 0, "");
-  static_assert(partial_ordering::equivalent == 0, "");
-  static_assert(partial_ordering::greater > 0, "");
-  static_assert(partial_ordering::unordered != 0, "");
+  static_assert(partial_ordering::less < 0);
+  static_assert(partial_ordering::equivalent == 0);
+  static_assert(partial_ordering::greater > 0);
+  static_assert(partial_ordering::unordered != 0);
 
-  static_assert(weak_ordering::less < 0, "");
-  static_assert(weak_ordering::equivalent == 0, "");
-  static_assert(weak_ordering::greater > 0, "");
+  static_assert(weak_ordering::less < 0);
+  static_assert(weak_ordering::equivalent == 0);
+  static_assert(weak_ordering::greater > 0);
 
-  static_assert(strong_ordering::less < 0, "");
-  static_assert(strong_ordering::equal == 0, "");
-  static_assert(strong_ordering::equivalent == 0, "");
-  static_assert(strong_ordering::greater > 0, "");
+  static_assert(strong_ordering::less < 0);
+  static_assert(strong_ordering::equal == 0);
+  static_assert(strong_ordering::equivalent == 0);
+  static_assert(strong_ordering::greater > 0);
 }
-#endif  // __cpp_inline_variables
 
 }  // namespace
 ABSL_NAMESPACE_END
diff --git a/absl/types/internal/any_span.h b/absl/types/internal/any_span.h
index ea85a44..00ee742 100644
--- a/absl/types/internal/any_span.h
+++ b/absl/types/internal/any_span.h
@@ -465,7 +465,7 @@
 
 template <typename T>
 bool EqualImpl(AnySpan<T> a, AnySpan<T> b) {
-  static_assert(std::is_const_v<T>, "");
+  static_assert(std::is_const_v<T>);
   return std::equal(a.begin(), a.end(), b.begin(), b.end());
 }
 
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h
index 148c957..f0f1af6 100644
--- a/absl/types/internal/span.h
+++ b/absl/types/internal/span.h
@@ -39,12 +39,6 @@
   return c.data();
 }
 
-// Before C++17, std::string::data returns a const char* in all cases.
-inline char* GetDataImpl(std::string& s,  // NOLINT(runtime/references)
-                         int) noexcept {
-  return &s[0];
-}
-
 template <typename C>
 constexpr auto GetData(C& c) noexcept  // NOLINT(runtime/references)
     -> decltype(GetDataImpl(c, 0)) {
@@ -86,7 +80,7 @@
 
 template <template <typename> class SpanT, typename T>
 constexpr bool EqualImpl(SpanT<T> a, SpanT<T> b) {
-  static_assert(std::is_const_v<T>, "");
+  static_assert(std::is_const_v<T>);
   return std::equal(a.begin(), a.end(), b.begin(), b.end());
 }
 
@@ -94,7 +88,7 @@
 constexpr bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
   // We can't use value_type since that is remove_cv_t<T>, so we go the long way
   // around.
-  static_assert(std::is_const_v<T>, "");
+  static_assert(std::is_const_v<T>);
   return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
 }
 
diff --git a/absl/types/optional_ref_test.cc b/absl/types/optional_ref_test.cc
index dda1624..c6f2e76 100644
--- a/absl/types/optional_ref_test.cc
+++ b/absl/types/optional_ref_test.cc
@@ -362,7 +362,7 @@
 TEST(OptionalRefTest, Constexpr) {
   static constexpr int foo = 123;
   constexpr optional_ref<const int> ref(foo);
-  static_assert(ref.has_value() && *ref == foo && ref.value() == foo, "");
+  static_assert(ref.has_value() && *ref == foo && ref.value() == foo);
 }
 
 }  // namespace
diff --git a/absl/types/span.h b/absl/types/span.h
index c33e294..41aba0a 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -39,8 +39,7 @@
 //    * bounds-checked access to `absl::Span` is accomplished with `at()`
 //      however `std::span` now supports the same as of the draft C++26 standard
 //    * `absl::Span` has compiler-provided move and copy constructors and
-//      assignment. This is due to them being specified as `constexpr`, but that
-//      implies const in C++11.
+//      assignment.
 //    * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
 //      `as_writable_bytes()` methods
 //    * `absl::Span` has no static extent template parameter, nor constructors
@@ -85,9 +84,6 @@
 
 // If std::ranges is available, mark Span as satisfying the `view` and
 // `borrowed_range` concepts, just like std::span.
-#if !defined(__has_include)
-#define __has_include(header) 0
-#endif
 #if __has_include(<version>)
 #include <version>  // NOLINT(misc-include-cleaner)
 #endif
@@ -220,7 +216,7 @@
   using absl_internal_is_view = std::true_type;
 
   // NOLINTNEXTLINE
-  static const size_type npos = ~(size_type(0));
+  static constexpr size_type npos = static_cast<size_type>(-1);
 
   constexpr Span() noexcept : Span(nullptr, 0) {}
   constexpr Span(pointer array ABSL_ATTRIBUTE_LIFETIME_BOUND,
@@ -510,9 +506,6 @@
   size_type len_;
 };
 
-template <typename T>
-const typename Span<T>::size_type Span<T>::npos;
-
 // Span relationals
 
 // Equality is compared element-by-element, while ordering is lexicographical.
diff --git a/ci/cmake_common.sh b/ci/cmake_common.sh
index 53d3a37..1804e14 100644
--- a/ci/cmake_common.sh
+++ b/ci/cmake_common.sh
@@ -14,6 +14,6 @@
 
 # The commit of GoogleTest to be used in the CMake tests in this directory.
 # Keep this in sync with the commit in the MODULE.bazel file.
-readonly ABSL_GOOGLETEST_VERSION="1.17.0"
+readonly ABSL_GOOGLETEST_VERSION="1.18.0"
 
 ABSL_GOOGLETEST_DOWNLOAD_URL="https://github.com/google/googletest/releases/download/v${ABSL_GOOGLETEST_VERSION}/googletest-${ABSL_GOOGLETEST_VERSION}.tar.gz"
diff --git a/ci/windows_msvc_bazel.bat b/ci/windows_msvc_bazel.bat
index 031d08f..a4bd3d7 100755
--- a/ci/windows_msvc_bazel.bat
+++ b/ci/windows_msvc_bazel.bat
@@ -46,7 +46,7 @@
   test ... ^
   --compilation_mode=%COMPILATION_MODE% ^
   --copt=/WX ^
-  --copt=/std:%STD% ^
+  --cxxopt=/std:%STD% ^
   --define=absl=1 ^
   --enable_bzlmod=true ^
   --keep_going ^
diff --git a/ci/windows_msvc_cmake.bat b/ci/windows_msvc_cmake.bat
index c0083a1..6fbc324 100755
--- a/ci/windows_msvc_cmake.bat
+++ b/ci/windows_msvc_cmake.bat
@@ -15,8 +15,8 @@
 SETLOCAL ENABLEDELAYEDEXPANSION
 
 :: The version of GoogleTest to be used in the CMake tests in this directory.
-:: Keep this in sync with the version in the WORKSPACE file.
-SET ABSL_GOOGLETEST_VERSION=1.17.0
+:: Keep this in sync with the version in the MODULE.bazel file.
+SET ABSL_GOOGLETEST_VERSION=1.18.0
 
 IF EXIST %KOKORO_GFILE_DIR%\distdir\googletest-%ABSL_GOOGLETEST_VERSION%.tar.gz (
   SET ABSL_GOOGLETEST_DOWNLOAD_URL=file://%KOKORO_GFILE_DIR%\distdir\googletest-%ABSL_GOOGLETEST_VERSION%.tar.gz