diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index a003649..55bd054 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -25,6 +25,7 @@
   "base/internal/low_level_alloc.cc"
   "base/internal/low_level_alloc.h"
   "base/internal/low_level_scheduling.h"
+  "base/internal/nullability_traits.h"
   "base/internal/per_thread_tls.h"
   "base/internal/poison.cc"
   "base/internal/poison.h"
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 2b380e6..c68883e 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -95,6 +95,20 @@
 )
 
 cc_library(
+    name = "nullability_traits_internal",
+    hdrs = ["internal/nullability_traits.h"],
+    copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    visibility = [
+        "//absl:__subpackages__",
+    ],
+    deps = [
+        ":config",
+        ":nullability",
+    ],
+)
+
+cc_library(
     name = "raw_logging_internal",
     srcs = ["internal/raw_logging.cc"],
     hdrs = ["internal/raw_logging.h"],
@@ -643,6 +657,18 @@
 )
 
 cc_test(
+    name = "nullability_traits_test",
+    srcs = ["internal/nullability_traits_test.cc"],
+    deps = [
+        ":config",
+        ":nullability",
+        ":nullability_traits_internal",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
+    ],
+)
+
+cc_test(
     name = "raw_logging_test",
     srcs = ["raw_logging_test.cc"],
     copts = ABSL_TEST_COPTS,
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 4eb1390..9dca989 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -107,6 +107,34 @@
 # Internal-only target, do not depend on directly.
 absl_cc_library(
   NAME
+    nullability_traits_internal
+  HDRS
+    "internal/nullability_traits.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  DEPS
+    absl::config
+    absl::nullability
+  PUBLIC
+)
+
+absl_cc_test(
+  NAME
+    nullability_traits_test
+  SRCS
+    "internal/nullability_traits_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
+  DEPS
+    absl::config
+    absl::nullability
+    absl::nullability_traits_internal
+    GTest::gtest_main
+)
+
+# Internal-only target, do not depend on directly.
+absl_cc_library(
+  NAME
     raw_logging_internal
   HDRS
     "internal/raw_logging.h"
diff --git a/absl/base/call_once_test.cc b/absl/base/call_once_test.cc
index 11d26c4..630e7ce 100644
--- a/absl/base/call_once_test.cc
+++ b/absl/base/call_once_test.cc
@@ -39,25 +39,25 @@
 
 // Function to be called from absl::call_once.  Waits for a notification.
 void WaitAndIncrement() {
-  counters_mu.Lock();
+  counters_mu.lock();
   ++call_once_invoke_count;
-  counters_mu.Unlock();
+  counters_mu.unlock();
 
   counters_mu.LockWhen(Condition(&done_blocking));
   ++call_once_finished_count;
-  counters_mu.Unlock();
+  counters_mu.unlock();
 }
 
 void ThreadBody() {
-  counters_mu.Lock();
+  counters_mu.lock();
   ++running_thread_count;
-  counters_mu.Unlock();
+  counters_mu.unlock();
 
   absl::call_once(once, WaitAndIncrement);
 
-  counters_mu.Lock();
+  counters_mu.lock();
   ++call_once_return_count;
-  counters_mu.Unlock();
+  counters_mu.unlock();
 }
 
 // Returns true if all threads are set up for the test.
@@ -89,17 +89,17 @@
   // Allow WaitAndIncrement to finish executing.  Once it does, the other
   // call_once waiters will be unblocked.
   done_blocking = true;
-  counters_mu.Unlock();
+  counters_mu.unlock();
 
   for (std::thread& thread : threads) {
     thread.join();
   }
 
-  counters_mu.Lock();
+  counters_mu.lock();
   EXPECT_EQ(call_once_invoke_count, 1);
   EXPECT_EQ(call_once_finished_count, 1);
   EXPECT_EQ(call_once_return_count, 10);
-  counters_mu.Unlock();
+  counters_mu.unlock();
 }
 
 }  // namespace
diff --git a/absl/base/internal/nullability_traits.h b/absl/base/internal/nullability_traits.h
new file mode 100644
index 0000000..790ec90
--- /dev/null
+++ b/absl/base/internal/nullability_traits.h
@@ -0,0 +1,71 @@
+// Copyright 2025 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_BASE_INTERNAL_NULLABILITY_TRAITS_H_
+#define ABSL_BASE_INTERNAL_NULLABILITY_TRAITS_H_
+
+#include <type_traits>
+
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+
+// `value` is true if the type `T` is compatible with nullability annotations
+// (is a raw pointer, a smart pointer, or marked with
+// ABSL_NULLABILITY_COMPATIBLE). Prefer to use the higher-level
+// `AddNonnullIfCompatible` if that is sufficient.
+//
+// NOTE: This should not be used to detect if the compiler is Clang (since
+// Clang is the only compiler that supports nullability annotations).
+#if defined(__clang__) && !defined(__OBJC__) && \
+    ABSL_HAVE_FEATURE(nullability_on_classes)
+template <class T, class = void>
+struct IsNullabilityCompatibleType {
+  constexpr static bool value = false;
+};
+
+template <class T>
+struct IsNullabilityCompatibleType<T, std::void_t<absl_nullable T>> {
+  constexpr static bool value = true;
+};
+#else
+// False when absl_nullable is a no-op (for non-Clang compilers or Objective-C.)
+template <class T, class = void>
+struct IsNullabilityCompatibleType {
+  constexpr static bool value = false;
+};
+#endif
+
+// A trait to add `absl_nonnull` to a type if it is compatible with nullability
+// annotations.
+template <typename T, bool ShouldAdd = IsNullabilityCompatibleType<T>::value>
+struct AddNonnullIfCompatible;
+
+template <typename T>
+struct AddNonnullIfCompatible<T, false> {
+  using type = T;
+};
+template <typename T>
+struct AddNonnullIfCompatible<T, true> {
+  using type = absl_nonnull T;
+};
+
+}  // namespace base_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_BASE_INTERNAL_NULLABILITY_TRAITS_H_
diff --git a/absl/base/internal/nullability_traits_test.cc b/absl/base/internal/nullability_traits_test.cc
new file mode 100644
index 0000000..2451239
--- /dev/null
+++ b/absl/base/internal/nullability_traits_test.cc
@@ -0,0 +1,98 @@
+// Copyright 2025 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/base/internal/nullability_traits.h"
+
+#include <memory>
+#include <type_traits>
+
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+namespace {
+
+struct NotSmartPtr {
+  int* x;
+};
+
+class ABSL_NULLABILITY_COMPATIBLE MySmartPtr : std::unique_ptr<int> {};
+
+// The IsNullabilityCompatibleType trait value can only be true when we define
+// `absl_nullable` (isn't a no-op).
+#if defined(__clang__) && !defined(__OBJC__) && \
+    ABSL_HAVE_FEATURE(nullability_on_classes)
+#define EXPECT_TRUE_IF_SUPPORTED EXPECT_TRUE
+#else
+#define EXPECT_TRUE_IF_SUPPORTED EXPECT_FALSE
+#endif
+
+TEST(NullabilityTraitsTest, IsNullabilityEligibleTypePrimitives) {
+  EXPECT_FALSE(IsNullabilityCompatibleType<int>::value);
+  EXPECT_FALSE(IsNullabilityCompatibleType<int*&>::value);
+
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<int*>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<int**>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<int* const>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<const int*>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<void (*)(int)>::value);
+}
+
+TEST(NullabilityTraitsTest, IsNullabilityCompatibleTypeAliases) {
+  using MyInt = int;
+  using MyIntPtr = int*;
+  EXPECT_FALSE(IsNullabilityCompatibleType<MyInt>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<MyIntPtr>::value);
+}
+
+TEST(NullabilityTraitsTest, IsNullabilityCompatibleTypeSmartPointers) {
+  EXPECT_TRUE_IF_SUPPORTED(
+      IsNullabilityCompatibleType<std::unique_ptr<int>>::value);
+  EXPECT_TRUE_IF_SUPPORTED(
+      IsNullabilityCompatibleType<std::shared_ptr<int>>::value);
+
+  EXPECT_FALSE(IsNullabilityCompatibleType<NotSmartPtr>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<NotSmartPtr*>::value);
+  EXPECT_TRUE_IF_SUPPORTED(IsNullabilityCompatibleType<MySmartPtr>::value);
+}
+
+#undef EXPECT_TRUE_IF_SUPPORTED
+
+TEST(NullabilityTraitsTest, AddNonnullIfCompatiblePassThroughPrimitives) {
+  EXPECT_TRUE((std::is_same_v<AddNonnullIfCompatible<int>::type, int>));
+  EXPECT_TRUE((std::is_same_v<AddNonnullIfCompatible<int*>::type, int*>));
+  EXPECT_TRUE(
+      (std::is_same_v<AddNonnullIfCompatible<int* const>::type, int* const>));
+}
+
+TEST(NullabilityTraitsTest, AddNonnullIfCompatiblePassThroughSmartPointers) {
+  EXPECT_TRUE(
+      (std::is_same_v<AddNonnullIfCompatible<std::unique_ptr<int>>::type,
+                      std::unique_ptr<int>>));
+  EXPECT_TRUE(
+      (std::is_same_v<AddNonnullIfCompatible<std::shared_ptr<int>>::type,
+                      std::shared_ptr<int>>));
+  EXPECT_TRUE(
+      (std::is_same_v<AddNonnullIfCompatible<NotSmartPtr>::type, NotSmartPtr>));
+  EXPECT_TRUE(
+      (std::is_same_v<AddNonnullIfCompatible<MySmartPtr>::type, MySmartPtr>));
+}
+
+}  // namespace
+}  // namespace base_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
index 875a36c..e750655 100644
--- a/absl/container/internal/raw_hash_set.cc
+++ b/absl/container/internal/raw_hash_set.cc
@@ -19,6 +19,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <cstring>
+#include <tuple>
 #include <utility>
 
 #include "absl/base/attributes.h"
@@ -154,21 +155,31 @@
 
 namespace {
 
+// Probes an array of control bits using a probe sequence,
+// and returns the mask corresponding to the first group with a deleted or empty
+// slot.
+inline Group::NonIterableBitMaskType probe_till_first_non_full_group(
+    const ctrl_t* ctrl, probe_seq<Group::kWidth>& seq,
+    [[maybe_unused]] size_t capacity) {
+  while (true) {
+    GroupFullEmptyOrDeleted g{ctrl + seq.offset()};
+    auto mask = g.MaskEmptyOrDeleted();
+    if (mask) {
+      return mask;
+    }
+    seq.next();
+    ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity && "full table!");
+  }
+}
+
 FindInfo find_first_non_full_from_h1(const ctrl_t* ctrl, size_t h1,
                                      size_t capacity) {
   auto seq = probe_h1(capacity, h1);
   if (IsEmptyOrDeleted(ctrl[seq.offset()])) {
     return {seq.offset(), /*probe_length=*/0};
   }
-  while (true) {
-    GroupFullEmptyOrDeleted g{ctrl + seq.offset()};
-    auto mask = g.MaskEmptyOrDeleted();
-    if (mask) {
-      return {seq.offset(mask.LowestBitSet()), seq.index()};
-    }
-    seq.next();
-    ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity && "full table!");
-  }
+  auto mask = probe_till_first_non_full_group(ctrl, seq, capacity);
+  return {seq.offset(mask.LowestBitSet()), seq.index()};
 }
 
 // Probes an array of control bits using a probe sequence derived from `hash`,
@@ -183,6 +194,16 @@
                                      common.capacity());
 }
 
+// Same as `find_first_non_full`, but returns the mask corresponding to the
+// first group with a deleted or empty slot.
+std::pair<FindInfo, Group::NonIterableBitMaskType> find_first_non_full_group(
+    const CommonFields& common, size_t hash) {
+  auto seq = probe(common, hash);
+  auto mask =
+      probe_till_first_non_full_group(common.control(), seq, common.capacity());
+  return {{seq.offset(), seq.index()}, mask};
+}
+
 // Whether a table fits in half a group. A half-group table fits entirely into a
 // probing group, i.e., has a capacity < `Group::kWidth`.
 //
@@ -749,7 +770,7 @@
   ABSL_SWISSTABLE_ASSERT(IsValidCapacity(new_capacity));
   ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity());
 
-  const size_t old_capacity = common.capacity();
+  [[maybe_unused]] const size_t old_capacity = common.capacity();
   [[maybe_unused]] ctrl_t* old_ctrl;
   [[maybe_unused]] void* old_slots;
   if constexpr (kMode == ResizeNonSooMode::kGuaranteedAllocated) {
@@ -758,7 +779,7 @@
   }
 
   const size_t slot_size = policy.slot_size;
-  const size_t slot_align = policy.slot_align;
+  [[maybe_unused]] const size_t slot_align = policy.slot_align;
   const bool has_infoz = infoz.IsSampled();
   void* alloc = policy.get_char_alloc(common);
 
@@ -1924,7 +1945,9 @@
 namespace {
 size_t PrepareInsertLargeImpl(CommonFields& common,
                               const PolicyFunctions& __restrict policy,
-                              size_t hash, FindInfo target) {
+                              size_t hash,
+                              Group::NonIterableBitMaskType mask_empty,
+                              FindInfo target_group) {
   ABSL_SWISSTABLE_ASSERT(!common.is_small());
   const GrowthInfo growth_info = common.growth_info();
   // When there are no deleted slots in the table
@@ -1935,23 +1958,27 @@
   }
   PrepareInsertCommon(common);
   common.growth_info().OverwriteEmptyAsFull();
-  SetCtrl(common, target.offset, H2(hash), policy.slot_size);
-  common.infoz().RecordInsert(hash, target.probe_length);
-  return target.offset;
+  target_group.offset += mask_empty.LowestBitSet();
+  target_group.offset &= common.capacity();
+  SetCtrl(common, target_group.offset, H2(hash), policy.slot_size);
+  common.infoz().RecordInsert(hash, target_group.probe_length);
+  return target_group.offset;
 }
 }  // namespace
 
 size_t PrepareInsertLarge(CommonFields& common,
                           const PolicyFunctions& __restrict policy, size_t hash,
-                          FindInfo target) {
+                          Group::NonIterableBitMaskType mask_empty,
+                          FindInfo target_group) {
   // NOLINTNEXTLINE(misc-static-assert)
   ABSL_SWISSTABLE_ASSERT(!SwisstableGenerationsEnabled());
-  return PrepareInsertLargeImpl(common, policy, hash, target);
+  return PrepareInsertLargeImpl(common, policy, hash, mask_empty, target_group);
 }
 
 size_t PrepareInsertLargeGenerationsEnabled(
     CommonFields& common, const PolicyFunctions& policy, size_t hash,
-    FindInfo target, absl::FunctionRef<size_t(size_t)> recompute_hash) {
+    Group::NonIterableBitMaskType mask_empty, FindInfo target_group,
+    absl::FunctionRef<size_t(size_t)> recompute_hash) {
   // NOLINTNEXTLINE(misc-static-assert)
   ABSL_SWISSTABLE_ASSERT(SwisstableGenerationsEnabled());
   if (common.should_rehash_for_bug_detection_on_insert()) {
@@ -1960,9 +1987,10 @@
     ResizeAllocatedTableWithSeedChange(
         common, policy, common.growth_left() > 0 ? cap : NextCapacity(cap));
     hash = recompute_hash(common.seed().seed());
-    target = find_first_non_full(common, hash);
+    std::tie(target_group, mask_empty) =
+        find_first_non_full_group(common, hash);
   }
-  return PrepareInsertLargeImpl(common, policy, hash, target);
+  return PrepareInsertLargeImpl(common, policy, hash, mask_empty, target_group);
 }
 
 namespace {
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 9f62700..f3e2065 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1728,29 +1728,35 @@
 // empty class cases.
 void* GetRefForEmptyClass(CommonFields& common);
 
-// Given the hash of a value not currently in the table and the first empty
-// slot in the probe sequence, finds a viable slot index to insert it at.
+// Given the hash of a value not currently in the table and the first group with
+// an empty slot in the probe sequence, finds a viable slot index to insert it
+// at.
 //
 // In case there's no space left, the table can be resized or rehashed
 // (for tables with deleted slots, see FindInsertPositionWithGrowthOrRehash).
 //
 // In the case of absence of deleted slots and positive growth_left, the element
-// can be inserted in the provided `target` position.
+// can be inserted in one of the empty slots in the provided `target_group`.
 //
 // When the table has deleted slots (according to GrowthInfo), the target
 // position will be searched one more time using `find_first_non_full`.
 //
 // REQUIRES: `!common.is_small()`.
 // REQUIRES: At least one non-full slot available.
-// REQUIRES: `target` is a valid empty position to insert.
+// REQUIRES: `mask_empty` is a mask containing empty slots for the
+//           `target_group`.
+// REQUIRES: `target_group` is a starting position for the group that has
+//            at least one empty slot.
 size_t PrepareInsertLarge(CommonFields& common, const PolicyFunctions& policy,
-                          size_t hash, FindInfo target);
+                          size_t hash, Group::NonIterableBitMaskType mask_empty,
+                          FindInfo target_group);
 
 // Same as above, but with generations enabled, we may end up changing the seed,
 // which means we need to be able to recompute the hash.
 size_t PrepareInsertLargeGenerationsEnabled(
     CommonFields& common, const PolicyFunctions& policy, size_t hash,
-    FindInfo target, absl::FunctionRef<size_t(size_t)> recompute_hash);
+    Group::NonIterableBitMaskType mask_empty, FindInfo target_group,
+    absl::FunctionRef<size_t(size_t)> recompute_hash);
 
 // A SwissTable.
 //
@@ -3203,14 +3209,15 @@
         }
         auto mask_empty = g.MaskEmpty();
         if (ABSL_PREDICT_TRUE(mask_empty)) {
-          size_t target = seq.offset(mask_empty.LowestBitSet());
+          size_t target_group_offset = seq.offset();
           index = SwisstableGenerationsEnabled()
                       ? PrepareInsertLargeGenerationsEnabled(
-                            common(), GetPolicyFunctions(), hash,
-                            FindInfo{target, seq.index()},
+                            common(), GetPolicyFunctions(), hash, mask_empty,
+                            FindInfo{target_group_offset, seq.index()},
                             HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})
-                      : PrepareInsertLarge(common(), GetPolicyFunctions(), hash,
-                                           FindInfo{target, seq.index()});
+                      : PrepareInsertLarge(
+                            common(), GetPolicyFunctions(), hash, mask_empty,
+                            FindInfo{target_group_offset, seq.index()});
           inserted = true;
           return;
         }
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index ed7cc49..7cc053e 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -14,6 +14,9 @@
 # limitations under the License.
 #
 
+load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
+load("@rules_cc//cc:cc_library.bzl", "cc_library")
+load("@rules_cc//cc:cc_test.bzl", "cc_test")
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h
index edf61de..10244b8 100644
--- a/absl/functional/function_ref.h
+++ b/absl/functional/function_ref.h
@@ -85,13 +85,12 @@
 //                  callback);
 template <typename R, typename... Args>
 class FunctionRef<R(Args...)> {
- private:
+ protected:
   // Used to disable constructors for objects that are not compatible with the
   // signature of this FunctionRef.
-  template <typename F, typename FR = std::invoke_result_t<F, Args&&...>>
+  template <typename F, typename... U>
   using EnableIfCompatible =
-      std::enable_if_t<std::conditional_t<std::is_void_v<R>, std::true_type,
-                                          std::is_invocable_r<R, FR()>>::value>;
+      std::enable_if_t<std::is_invocable_r<R, F, U..., Args...>::value>;
 
  public:
   // Constructs a FunctionRef from any invocable type.
@@ -111,9 +110,8 @@
   //
   // This overload is also used for references to functions, since references to
   // functions can decay to function pointers implicitly.
-  template <
-      typename F, typename = EnableIfCompatible<F*>,
-      absl::functional_internal::EnableIf<absl::is_function<F>::value> = 0>
+  template <typename F, typename = EnableIfCompatible<F*>,
+            absl::functional_internal::EnableIf<std::is_function_v<F>> = 0>
   // NOLINTNEXTLINE(google-explicit-constructor)
   FunctionRef(F* f ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
       : invoker_(&absl::functional_internal::InvokeFunction<F*, R, Args...>) {
@@ -126,22 +124,27 @@
   // `F` at compile time. This allows calling arbitrary functions while avoiding
   // an indirection.
   // Needs C++20 as `nontype_t` needs C++20 for `auto` template parameters.
-  template <auto F>
+  template <auto F, typename = EnableIfCompatible<decltype(F)>>
   FunctionRef(nontype_t<F>) noexcept  // NOLINT(google-explicit-constructor)
       : invoker_(&absl::functional_internal::InvokeFunction<decltype(F), F, R,
                                                             Args...>) {}
 
-  template <auto F, typename Obj>
+  template <
+      auto F, typename Obj,
+      typename = EnableIfCompatible<decltype(F), std::remove_reference_t<Obj>&>,
+      absl::functional_internal::EnableIf<!std::is_rvalue_reference_v<Obj&&>> =
+          0>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  FunctionRef(nontype_t<F>, Obj&& obj) noexcept
+  FunctionRef(nontype_t<F>, Obj&& obj ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
       : invoker_(&absl::functional_internal::InvokeObject<Obj&, decltype(F), F,
                                                           R, Args...>) {
     ptr_.obj = std::addressof(obj);
   }
 
-  template <auto F, typename Obj>
+  template <auto F, typename Obj,
+            typename = EnableIfCompatible<decltype(F), Obj*>>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  FunctionRef(nontype_t<F>, Obj* obj) noexcept
+  FunctionRef(nontype_t<F>, Obj* obj ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
       : invoker_(&absl::functional_internal::InvokePtr<Obj, decltype(F), F, R,
                                                        Args...>) {
     ptr_.obj = obj;
@@ -161,42 +164,72 @@
 // Allow const qualified function signatures. Since FunctionRef requires
 // constness anyway we can just make this a no-op.
 template <typename R, typename... Args>
-class FunctionRef<R(Args...) const> : public FunctionRef<R(Args...)> {
+class FunctionRef<R(Args...) const> : private FunctionRef<R(Args...)> {
   using Base = FunctionRef<R(Args...)>;
 
-  template <typename F, typename T = void>
-  using EnableIfCallable =
-      std::enable_if_t<!std::is_same_v<FunctionRef, absl::remove_cvref_t<F>> &&
-                           std::is_invocable_r_v<R, F, Args...> &&
-                           std::is_constructible_v<Base, F>,
-                       T>;
+  template <typename F, typename... U>
+  using EnableIfCompatible =
+      typename Base::template EnableIfCompatible<F, U...>;
 
  public:
-  template <typename F, typename = EnableIfCallable<const F&>>
+  template <
+      typename F,
+      typename = EnableIfCompatible<std::enable_if_t<
+          !std::is_same_v<FunctionRef, absl::remove_cvref_t<F>>, const F&>>>
   // NOLINTNEXTLINE(google-explicit-constructor)
   FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept : Base(f) {}
 
-  template <typename F,
-            typename = std::enable_if_t<std::is_constructible_v<Base, F*>>>
+  template <typename F, typename = EnableIfCompatible<F*>,
+            absl::functional_internal::EnableIf<std::is_function_v<F>> = 0>
   // NOLINTNEXTLINE(google-explicit-constructor)
   FunctionRef(F* f ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept : Base(f) {}
 
 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
-  template <auto F, typename = EnableIfCallable<decltype(F)>>
+  template <auto F, typename = EnableIfCompatible<decltype(F)>>
   // NOLINTNEXTLINE(google-explicit-constructor)
   FunctionRef(nontype_t<F> arg) noexcept : Base(arg) {}
 
-  template <auto F, typename Obj, typename = EnableIfCallable<decltype(F)>>
+  template <auto F, typename Obj,
+            typename = EnableIfCompatible<decltype(F),
+                                          const std::remove_reference_t<Obj>&>,
+            absl::functional_internal::EnableIf<
+                !std::is_rvalue_reference_v<Obj&&>> = 0>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  FunctionRef(nontype_t<F> arg, Obj&& obj) noexcept
+  FunctionRef(nontype_t<F> arg,
+              Obj&& obj ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
       : Base(arg, std::forward<Obj>(obj)) {}
 
-  template <auto F, typename Obj, typename = EnableIfCallable<decltype(F)>>
+  template <auto F, typename Obj,
+            typename = EnableIfCompatible<decltype(F), const Obj*>>
   // NOLINTNEXTLINE(google-explicit-constructor)
-  FunctionRef(nontype_t<F> arg, Obj* obj) noexcept : Base(arg, obj) {}
+  FunctionRef(nontype_t<F> arg,
+              const Obj* obj ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
+      : Base(arg, obj) {}
 #endif
+
+  using Base::operator();
 };
 
+template <class F>
+FunctionRef(F*) -> FunctionRef<F>;
+
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+template <auto Func>
+FunctionRef(nontype_t<Func>)
+    -> FunctionRef<std::remove_pointer_t<decltype(Func)>>;
+
+template <class M, class T, M T::* Func, class U>
+FunctionRef(nontype_t<Func>, U&&)
+    -> FunctionRef<std::enable_if_t<std::is_member_pointer_v<M T::*>, M>>;
+
+template <class M, class T, M T::* Func, class U>
+FunctionRef(nontype_t<Func>, U&&) -> FunctionRef<std::enable_if_t<
+    std::is_object_v<M>, std::invoke_result_t<decltype(Func), U&>()>>;
+
+template <class R, class T, class... Args, R (*Func)(T, Args...), class U>
+FunctionRef(nontype_t<Func>, U&&) -> FunctionRef<R(Args...)>;
+#endif
+
 ABSL_NAMESPACE_END
 }  // namespace absl
 
diff --git a/absl/functional/function_ref_test.cc b/absl/functional/function_ref_test.cc
index c8ff080..26db103 100644
--- a/absl/functional/function_ref_test.cc
+++ b/absl/functional/function_ref_test.cc
@@ -30,6 +30,11 @@
 ABSL_NAMESPACE_BEGIN
 namespace {
 
+struct Class {
+  int Func() { return 42; }
+  int CFunc() const { return 43; }
+};
+
 int Function() { return 1337; }
 
 template <typename T>
@@ -312,6 +317,7 @@
   EXPECT_EQ(42, FunctionRef<int()>(s)());
   EXPECT_EQ(1337, FunctionRef<int() const>(s)());
   EXPECT_EQ(1337, FunctionRef<int()>(std::as_const(s))());
+  EXPECT_EQ(1337, FunctionRef<int() const>(std::as_const(s))());
 }
 
 TEST(FunctionRefTest, Lambdas) {
@@ -342,11 +348,46 @@
 }
 
 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
-TEST(FunctionRefTest, NonTypeParameter) {
-  EXPECT_EQ(1337, FunctionRef<int()>(nontype<&Function>)());
-  EXPECT_EQ(42, FunctionRef<int()>(nontype<&Copy<int>>, 42)());
-  EXPECT_EQ(42, FunctionRef<int()>(nontype<&Dereference<int>>,
-                                   &std::integral_constant<int, 42>::value)());
+static_assert(std::is_same_v<decltype(FunctionRef(nontype<&Class::Func>,
+                                                  std::declval<Class&>())),
+                             FunctionRef<int()>>);
+static_assert(std::is_same_v<decltype(FunctionRef(nontype<&Class::CFunc>,
+                                                  std::declval<Class&>())),
+                             FunctionRef<int() const>>);
+
+static_assert(std::is_same_v<decltype(FunctionRef(nontype<&Class::Func>,
+                                                  std::declval<Class*>())),
+                             FunctionRef<int()>>);
+static_assert(std::is_same_v<decltype(FunctionRef(nontype<&Class::CFunc>,
+                                                  std::declval<Class*>())),
+                             FunctionRef<int() const>>);
+
+TEST(FunctionRefTest, NonTypeParameterWithTemporaries) {
+  static_assert(!std::is_constructible_v<FunctionRef<int()>,
+                                         nontype_t<&Class::Func>, Class&&>);
+  static_assert(
+      !std::is_constructible_v<FunctionRef<int()>, nontype_t<&Class::Func>,
+                               const Class&&>);
+  static_assert(!std::is_constructible_v<FunctionRef<int() const>,
+                                         nontype_t<&Class::CFunc>, Class&&>);
+  static_assert(
+      !std::is_constructible_v<FunctionRef<int() const>,
+                               nontype_t<&Class::CFunc>, const Class&&>);
+}
+
+TEST(FunctionRefTest, NonTypeParameterWithDeductionGuides) {
+  EXPECT_EQ(1337, FunctionRef(nontype<&Function>)());
+  EXPECT_EQ(42, FunctionRef(nontype<&Copy<int>>,
+                            std::integral_constant<int, 42>::value)());
+  EXPECT_EQ(42, FunctionRef(nontype<&Dereference<int>>,
+                            &std::integral_constant<int, 42>::value)());
+
+  Class c;
+  EXPECT_EQ(42, FunctionRef<int()>(nontype<&Class::Func>, c)());
+  EXPECT_EQ(43, FunctionRef<int() const>(nontype<&Class::CFunc>, c)());
+
+  EXPECT_EQ(42, FunctionRef<int()>(nontype<&Class::Func>, &c)());
+  EXPECT_EQ(43, FunctionRef<int() const>(nontype<&Class::CFunc>, &c)());
 }
 #endif
 
diff --git a/absl/functional/internal/function_ref.h b/absl/functional/internal/function_ref.h
index 0796364..543b30f 100644
--- a/absl/functional/internal/function_ref.h
+++ b/absl/functional/internal/function_ref.h
@@ -81,22 +81,37 @@
 template <typename Obj, typename Fun, Fun F, typename R, typename... Args>
 R InvokeObject(VoidPtr ptr, typename ForwardT<Args>::type... args) {
   using T = std::remove_reference_t<Obj>;
-  return static_cast<R>(
-      F(std::forward<Obj>(*const_cast<T*>(static_cast<const T*>(ptr.obj))),
+  Obj&& obj =
+      std::forward<Obj>(*const_cast<T*>(static_cast<const T*>(ptr.obj)));
+  // Avoid std::invoke() since the callee is a known function at compile time
+  if constexpr (std::is_member_function_pointer_v<Fun>) {
+    return static_cast<R>((std::forward<Obj>(obj).*F)(
         std::forward<typename ForwardT<Args>::type>(args)...));
+  } else {
+    return static_cast<R>(
+        F(std::forward<Obj>(obj),
+          std::forward<typename ForwardT<Args>::type>(args)...));
+  }
 }
 
 template <typename T, typename Fun, Fun F, typename R, typename... Args>
 R InvokePtr(VoidPtr ptr, typename ForwardT<Args>::type... args) {
-  return static_cast<R>(
-      F(const_cast<T*>(static_cast<const T*>(ptr.obj)),
-        std::forward<typename ForwardT<Args>::type>(args)...));
+  T* obj = const_cast<T*>(static_cast<const T*>(ptr.obj));
+  // Avoid std::invoke() since the callee is a known function at compile time
+  if constexpr (std::is_member_function_pointer_v<Fun>) {
+    return static_cast<R>(
+        (obj->*F)(std::forward<typename ForwardT<Args>::type>(args)...));
+  } else {
+    return static_cast<R>(
+        F(obj, std::forward<typename ForwardT<Args>::type>(args)...));
+  }
 }
 
 template <typename Fun, typename R, typename... Args>
 R InvokeFunction(VoidPtr ptr, typename ForwardT<Args>::type... args) {
   auto f = reinterpret_cast<Fun>(ptr.fun);
-  return static_cast<R>(std::invoke(f, std::forward<Args>(args)...));
+  return static_cast<R>(
+      std::invoke(f, std::forward<typename ForwardT<Args>::type>(args)...));
 }
 
 template <typename Fun, Fun F, typename R, typename... Args>
diff --git a/absl/log/BUILD.bazel b/absl/log/BUILD.bazel
index 3e965ab..5bc7150 100644
--- a/absl/log/BUILD.bazel
+++ b/absl/log/BUILD.bazel
@@ -80,6 +80,8 @@
         ":log",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:nullability",
+        "//absl/base:nullability_traits_internal",
         "//absl/strings",
     ],
 )
diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt
index c972c17..51f399e 100644
--- a/absl/log/CMakeLists.txt
+++ b/absl/log/CMakeLists.txt
@@ -466,6 +466,8 @@
     absl::config
     absl::core_headers
     absl::log
+    absl::nullability
+    absl::nullability_traits_internal
     absl::strings
   PUBLIC
 )
diff --git a/absl/log/die_if_null.cc b/absl/log/die_if_null.cc
index 19c6a28..0d0b78e 100644
--- a/absl/log/die_if_null.cc
+++ b/absl/log/die_if_null.cc
@@ -15,6 +15,7 @@
 #include "absl/log/die_if_null.h"
 
 #include "absl/base/config.h"
+#include "absl/base/nullability.h"
 #include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 
@@ -22,7 +23,8 @@
 ABSL_NAMESPACE_BEGIN
 namespace log_internal {
 
-void DieBecauseNull(const char* file, int line, const char* exprtext) {
+void DieBecauseNull(const char* absl_nonnull file, int line,
+                    const char* absl_nonnull exprtext) {
   LOG(FATAL).AtLocation(file, line)
       << absl::StrCat("Check failed: '", exprtext, "' Must be non-null");
 }
diff --git a/absl/log/die_if_null.h b/absl/log/die_if_null.h
index 8597976..ac7dbe6 100644
--- a/absl/log/die_if_null.h
+++ b/absl/log/die_if_null.h
@@ -23,10 +23,13 @@
 
 #include <stdint.h>
 
+#include <type_traits>
 #include <utility>
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
+#include "absl/base/internal/nullability_traits.h"
+#include "absl/base/nullability.h"
 #include "absl/base/optimization.h"
 
 // ABSL_DIE_IF_NULL()
@@ -56,12 +59,30 @@
 // generates less code than its implementation would if inlined, for a slight
 // code size reduction each time `ABSL_DIE_IF_NULL` is called.
 [[noreturn]] ABSL_ATTRIBUTE_NOINLINE void DieBecauseNull(
-    const char* file, int line, const char* exprtext);
+    const char* absl_nonnull file, int line, const char* absl_nonnull exprtext);
 
 // Helper for `ABSL_DIE_IF_NULL`.
+
+// Since we use `remove_reference_t` before `AddNonnullIfCompatible`, we need
+// to explicitly have overloads for both lvalue reference and rvalue reference
+// arguments and returns.
 template <typename T>
-[[nodiscard]] T DieIfNull(const char* file, int line, const char* exprtext,
-                          T&& t) {
+[[nodiscard]] typename absl::base_internal::AddNonnullIfCompatible<
+    std::remove_reference_t<T>>::type&
+DieIfNull(const char* absl_nonnull file, int line,
+          const char* absl_nonnull exprtext, T& t) {
+  if (ABSL_PREDICT_FALSE(t == nullptr)) {
+    // Call a non-inline helper function for a small code size improvement.
+    DieBecauseNull(file, line, exprtext);
+  }
+  return t;
+}
+
+template <typename T>
+[[nodiscard]] typename absl::base_internal::AddNonnullIfCompatible<
+    std::remove_reference_t<T>>::type&&
+DieIfNull(const char* absl_nonnull file, int line,
+          const char* absl_nonnull exprtext, T&& t) {
   if (ABSL_PREDICT_FALSE(t == nullptr)) {
     // Call a non-inline helper function for a small code size improvement.
     DieBecauseNull(file, line, exprtext);
diff --git a/absl/log/internal/log_message.cc b/absl/log/internal/log_message.cc
index 3aed3a2..52ab3d9 100644
--- a/absl/log/internal/log_message.cc
+++ b/absl/log/internal/log_message.cc
@@ -150,7 +150,7 @@
 }  // namespace
 
 struct LogMessage::LogMessageData final {
-  LogMessageData(const char* absl_nonnull file, int line,
+  LogMessageData(absl::string_view file, int line,
                  absl::LogSeverity severity, absl::Time timestamp);
   LogMessageData(const LogMessageData&) = delete;
   LogMessageData& operator=(const LogMessageData&) = delete;
@@ -202,7 +202,7 @@
   void FinalizeEncodingAndFormat();
 };
 
-LogMessage::LogMessageData::LogMessageData(const char* absl_nonnull file,
+LogMessage::LogMessageData::LogMessageData(absl::string_view file,
                                            int line, absl::LogSeverity severity,
                                            absl::Time timestamp)
     : extra_sinks_only(false), manipulated(nullptr) {
@@ -275,6 +275,9 @@
 
 LogMessage::LogMessage(const char* absl_nonnull file, int line,
                        absl::LogSeverity severity)
+  : LogMessage(absl::string_view(file), line, severity) {}
+LogMessage::LogMessage(absl::string_view file, int line,
+                       absl::LogSeverity severity)
     : data_(absl::make_unique<LogMessageData>(file, line, severity,
                                               absl::Now())) {
   data_->first_fatal = false;
diff --git a/absl/log/internal/log_message.h b/absl/log/internal/log_message.h
index 1aaf05e..5b6eed3 100644
--- a/absl/log/internal/log_message.h
+++ b/absl/log/internal/log_message.h
@@ -64,9 +64,13 @@
   struct WarningTag {};
   struct ErrorTag {};
 
-  // Used for `LOG`.
+  // Used for `LOG`.  Taking `const char *` instead of `string_view` keeps
+  // callsites a little bit smaller at the cost of doing `strlen` at runtime.
   LogMessage(const char* absl_nonnull file, int line,
              absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD;
+  // Used for FFI integrations that don't have a NUL-terminated string.
+  LogMessage(absl::string_view file, int line,
+             absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD;
   // These constructors are slightly smaller/faster to call; the severity is
   // curried into the function pointer.
   LogMessage(const char* absl_nonnull file, int line,