Annotate more Abseil container methods with [[clang::lifetime_capture_by(...)]] and make them all forward to the non-captured overload

This will allow catching some lifetime issues such as the following:
```
absl::btree_set<absl::string_view> s;
s.insert(std::string(...));  // dangling
```

It also deduplicates the source of truth for each set of identical overloads.

PiperOrigin-RevId: 736646161
Change-Id: I20453093d0c57c8a6ab080dc576c94a993147714
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index f1026a5..37b5f2a 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -659,11 +659,13 @@
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
+        ":common_policy_traits",
         ":container_memory",
         ":raw_hash_set",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:throw_delegate",
+        "//absl/meta:type_traits",
     ],
 )
 
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 1419df7..39ff083 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -720,9 +720,11 @@
     ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::config
+    absl::common_policy_traits
     absl::container_memory
     absl::core_headers
     absl::raw_hash_set
+    absl::type_traits
     absl::throw_delegate
   PUBLIC
 )
diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h
index a68ce44..551d621 100644
--- a/absl/container/internal/btree_container.h
+++ b/absl/container/internal/btree_container.h
@@ -18,6 +18,7 @@
 #include <algorithm>
 #include <initializer_list>
 #include <iterator>
+#include <type_traits>
 #include <utility>
 
 #include "absl/base/attributes.h"
@@ -451,6 +452,29 @@
   template <class K>
   using key_arg = typename super_type::template key_arg<K>;
 
+  // NOTE: The mess here is to shorten the code for the (very repetitive)
+  // function overloads, and to allow the lifetime-bound overloads to dispatch
+  // to the non-lifetime-bound overloads, to ensure there is a single source of
+  // truth for each overload set.
+  //
+  // Enabled if an assignment from the given type would require the
+  // source object to remain alive for the life of the element.
+  //
+  // TODO(b/402804213): Remove these traits and simplify the overloads whenever
+  // we have a better mechanism available to handle lifetime analysis.
+  template <class K, bool Value, typename = void>
+  using LifetimeBoundK =
+      HasValue<Value, type_traits_internal::IsLifetimeBoundAssignment<
+                          typename Tree::key_type, K>>;
+  template <class M, bool Value, typename = void>
+  using LifetimeBoundV =
+      HasValue<Value, type_traits_internal::IsLifetimeBoundAssignment<
+                          typename Tree::params_type::mapped_type, M>>;
+  template <class K, bool KValue, class M, bool MValue, typename... Dummy>
+  using LifetimeBoundKV =
+      absl::conjunction<LifetimeBoundK<K, KValue, absl::void_t<Dummy...>>,
+                        LifetimeBoundV<M, MValue>>;
+
  public:
   using key_type = typename Tree::key_type;
   using mapped_type = typename params_type::mapped_type;
@@ -464,85 +488,161 @@
   using super_type::super_type;
   btree_map_container() {}
 
+  // TODO(b/402804213): Remove these macros whenever we have a better mechanism
+  // available to handle lifetime analysis.
+#define ABSL_INTERNAL_X(Func, Callee, KQual, MQual, KValue, MValue, ...)       \
+  template <                                                                   \
+      typename K = key_type, class M,                                          \
+      ABSL_INTERNAL_IF_NOR(                                                    \
+          KValue, MValue,                                                      \
+          int = (EnableIf<LifetimeBoundKV<K, KValue, M, MValue,                \
+                                          IfRRef<int KQual>::AddPtr<K>,        \
+                                          IfRRef<int MQual>::AddPtr<M>>>()),   \
+          ABSL_INTERNAL_SINGLE_ARG(                                            \
+              int &...,                                                        \
+              decltype(EnableIf<LifetimeBoundKV<K, KValue, M, MValue>>()) =    \
+                  0))>                                                         \
+  decltype(auto) Func(__VA_ARGS__ key_arg<K> KQual k ABSL_INTERNAL_IF(         \
+                          KValue, ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)),  \
+                      M MQual obj ABSL_INTERNAL_IF(                            \
+                          MValue, ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)))  \
+      ABSL_ATTRIBUTE_LIFETIME_BOUND {                                          \
+    return ABSL_INTERNAL_IF_OR(KValue, MValue, (this->template Func<K, M, 0>), \
+                               Callee)(                                        \
+        __VA_ARGS__ std::forward<decltype(k)>(k),                              \
+        std::forward<decltype(obj)>(obj));                                     \
+  }                                                                            \
+  friend struct std::enable_if<false> /* just to force a semicolon */
   // Insertion routines.
   // Note: the nullptr template arguments and extra `const M&` overloads allow
   // for supporting bitfield arguments.
-  template <typename K = key_type, class M>
-  std::pair<iterator, bool> insert_or_assign(const key_arg<K> &k, const M &obj)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(k, obj);
-  }
-  template <typename K = key_type, class M, K * = nullptr>
-  std::pair<iterator, bool> insert_or_assign(key_arg<K> &&k, const M &obj)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(std::forward<K>(k), obj);
-  }
-  template <typename K = key_type, class M, M * = nullptr>
-  std::pair<iterator, bool> insert_or_assign(const key_arg<K> &k, M &&obj)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(k, std::forward<M>(obj));
-  }
-  template <typename K = key_type, class M, K * = nullptr, M * = nullptr>
-  std::pair<iterator, bool> insert_or_assign(key_arg<K> &&k, M &&obj)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(std::forward<K>(k), std::forward<M>(obj));
-  }
-  template <typename K = key_type, class M>
-  iterator insert_or_assign(const_iterator hint, const key_arg<K> &k,
-                            const M &obj) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_hint_impl(hint, k, obj);
-  }
-  template <typename K = key_type, class M, K * = nullptr>
-  iterator insert_or_assign(const_iterator hint, key_arg<K> &&k,
-                            const M &obj) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_hint_impl(hint, std::forward<K>(k), obj);
-  }
-  template <typename K = key_type, class M, M * = nullptr>
-  iterator insert_or_assign(const_iterator hint, const key_arg<K> &k,
-                            M &&obj) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_hint_impl(hint, k, std::forward<M>(obj));
-  }
-  template <typename K = key_type, class M, K * = nullptr, M * = nullptr>
-  iterator insert_or_assign(const_iterator hint, key_arg<K> &&k,
-                            M &&obj) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_hint_impl(hint, std::forward<K>(k),
-                                      std::forward<M>(obj));
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  false, false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  false, true);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  true, false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  true, true);
 
-  template <typename K = key_type, typename... Args,
-            typename absl::enable_if_t<
-                !std::is_convertible<K, const_iterator>::value, int> = 0>
-  std::pair<iterator, bool> try_emplace(const key_arg<K> &k, Args &&...args)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return try_emplace_impl(k, std::forward<Args>(args)...);
-  }
-  template <typename K = key_type, typename... Args,
-            typename absl::enable_if_t<
-                !std::is_convertible<K, const_iterator>::value, int> = 0>
-  std::pair<iterator, bool> try_emplace(key_arg<K> &&k, Args &&...args)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...);
-  }
-  template <typename K = key_type, typename... Args>
-  iterator try_emplace(const_iterator hint, const key_arg<K> &k,
-                       Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return try_emplace_hint_impl(hint, k, std::forward<Args>(args)...);
-  }
-  template <typename K = key_type, typename... Args>
-  iterator try_emplace(const_iterator hint, key_arg<K> &&k,
-                       Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return try_emplace_hint_impl(hint, std::forward<K>(k),
-                                 std::forward<Args>(args)...);
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
+                  false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
+                  true);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
+                  false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
+                  true);
 
-  template <typename K = key_type>
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
+                  false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
+                  true);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
+                  false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
+                  true);
+
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false,
+                  false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false, true);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, false);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, true);
+
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
+                  const &, false, false,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
+                  const &, false, true,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
+                  const &, true, false,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
+                  const &, true, true,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
+                  false, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
+                  false, true, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
+                  true, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
+                  true, true, const_iterator(hint) ABSL_INTERNAL_COMMA);
+
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
+                  false, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
+                  false, true, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
+                  true, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
+                  true, true, const_iterator(hint) ABSL_INTERNAL_COMMA);
+
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, false,
+                  false, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, false,
+                  true, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, true,
+                  false, const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, true,
+                  true, const_iterator(hint) ABSL_INTERNAL_COMMA);
+#undef ABSL_INTERNAL_X
+
+#define ABSL_INTERNAL_X(Func, Callee, KQual, KValue, ...)                      \
+  template <class K = key_type,                                                \
+            ABSL_INTERNAL_IF(KValue, class... Args,                            \
+                             int = EnableIf<LifetimeBoundK<                    \
+                                 K, KValue, IfRRef<int KQual>::AddPtr<K>>>()), \
+            ABSL_INTERNAL_IF(                                                  \
+                KValue,                                                        \
+                decltype(EnableIf<LifetimeBoundK<                              \
+                             K, KValue, IfRRef<int KQual>::AddPtr<K>>>()) = 0, \
+                class... Args),                                                \
+            std::enable_if_t<!std::is_convertible<K, const_iterator>::value,   \
+                             int> = 0>                                         \
+  decltype(auto) Func(__VA_ARGS__ key_arg<K> KQual k ABSL_INTERNAL_IF(         \
+                          KValue, ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)),  \
+                      Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {          \
+    return ABSL_INTERNAL_IF(KValue, (this->template Func<K, 0>), Callee)(      \
+        __VA_ARGS__ std::forward<decltype(k)>(k),                              \
+        std::forward<decltype(args)>(args)...);                                \
+  }                                                                            \
+  friend struct std::enable_if<false> /* just to force a semicolon */
+  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, const &, false);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, const &, true);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, &&, false);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, &&, true);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, const &, false,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, const &, true,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, &&, false,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, &&, true,
+                  const_iterator(hint) ABSL_INTERNAL_COMMA);
+#undef ABSL_INTERNAL_X
+
+  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>()>
   mapped_type &operator[](const key_arg<K> &k) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace(k).first->second;
   }
-  template <typename K = key_type>
+  template <class K = key_type, int &..., EnableIf<LifetimeBoundK<K, true>> = 0>
+  mapped_type &operator[](
+      const key_arg<K> &k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+      ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template operator[]<K, 0>(k);
+  }
+  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>()>
   mapped_type &operator[](key_arg<K> &&k) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace(std::forward<K>(k)).first->second;
   }
+  template <class K = key_type, int &..., EnableIf<LifetimeBoundK<K, true>> = 0>
+  mapped_type &operator[](key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(
+      this)) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template operator[]<K, 0>(std::forward<K>(k));
+  }
 
   template <typename K = key_type>
   mapped_type &at(const key_arg<K> &key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h
index 9239bb4..416e0e0 100644
--- a/absl/container/internal/common.h
+++ b/absl/container/internal/common.h
@@ -21,10 +21,61 @@
 #include "absl/meta/type_traits.h"
 #include "absl/types/optional.h"
 
+// TODO(b/402804213): Clean up these macros when no longer needed.
+#define ABSL_INTERNAL_SINGLE_ARG(...) __VA_ARGS__
+
+#define ABSL_INTERNAL_IF_true(if_satisfied, ...) if_satisfied
+#define ABSL_INTERNAL_IF_false(if_satisfied, ...) __VA_ARGS__
+#define ABSL_INTERNAL_IF(cond1, if_satisfied, ...) \
+  ABSL_INTERNAL_IF_##cond1(if_satisfied, __VA_ARGS__)
+
+#define ABSL_INTERNAL_IF_true_AND_true ABSL_INTERNAL_IF_true
+#define ABSL_INTERNAL_IF_false_AND_false ABSL_INTERNAL_IF_false
+#define ABSL_INTERNAL_IF_true_AND_false ABSL_INTERNAL_IF_false_AND_false
+#define ABSL_INTERNAL_IF_false_AND_true ABSL_INTERNAL_IF_false_AND_false
+#define ABSL_INTERNAL_IF_AND(cond1, cond2, if_satisfied, ...) \
+  ABSL_INTERNAL_IF_##cond1##_AND_##cond2(if_satisfied, __VA_ARGS__)
+
+#define ABSL_INTERNAL_IF_true_OR_true ABSL_INTERNAL_IF_true
+#define ABSL_INTERNAL_IF_false_OR_false ABSL_INTERNAL_IF_false
+#define ABSL_INTERNAL_IF_true_OR_false ABSL_INTERNAL_IF_true_OR_true
+#define ABSL_INTERNAL_IF_false_OR_true ABSL_INTERNAL_IF_true_OR_true
+#define ABSL_INTERNAL_IF_OR(cond1, cond2, if_satisfied, ...) \
+  ABSL_INTERNAL_IF_##cond1##_OR_##cond2(if_satisfied, __VA_ARGS__)
+
+#define ABSL_INTERNAL_IF_true_NOR_true ABSL_INTERNAL_IF_false_AND_false
+#define ABSL_INTERNAL_IF_false_NOR_false ABSL_INTERNAL_IF_true_AND_true
+#define ABSL_INTERNAL_IF_true_NOR_false ABSL_INTERNAL_IF_false_AND_true
+#define ABSL_INTERNAL_IF_false_NOR_true ABSL_INTERNAL_IF_true_AND_false
+#define ABSL_INTERNAL_IF_NOR(cond1, cond2, if_satisfied, ...) \
+  ABSL_INTERNAL_IF_##cond1##_NOR_##cond2(if_satisfied, __VA_ARGS__)
+
+#define ABSL_INTERNAL_COMMA ,
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
 
+// TODO(b/402804213): Clean up these traits when no longer needed or
+// deduplicate them with absl::functional_internal::EnableIf.
+template <class Cond>
+using EnableIf = std::enable_if_t<Cond::value, int>;
+
+template <bool Value, class T>
+using HasValue = std::conditional_t<Value, T, absl::negation<T>>;
+
+template <class T>
+struct IfRRef {
+  template <class Other>
+  using AddPtr = Other;
+};
+
+template <class T>
+struct IfRRef<T&&> {
+  template <class Other>
+  using AddPtr = Other*;
+};
+
 template <class, class = void>
 struct IsTransparent : std::false_type {};
 template <class T>
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h
index 8ca0849..a3ec0bb 100644
--- a/absl/container/internal/raw_hash_map.h
+++ b/absl/container/internal/raw_hash_map.h
@@ -22,8 +22,10 @@
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/throw_delegate.h"
+#include "absl/container/internal/common_policy_traits.h"
 #include "absl/container/internal/container_memory.h"
 #include "absl/container/internal/raw_hash_set.h"  // IWYU pragma: export
+#include "absl/meta/type_traits.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -48,6 +50,31 @@
       typename KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>::
           template type<K, typename Policy::key_type>;
 
+  // NOTE: The mess here is to shorten the code for the (very repetitive)
+  // function overloads, and to allow the lifetime-bound overloads to dispatch
+  // to the non-lifetime-bound overloads, to ensure there is a single source of
+  // truth for each overload set.
+  //
+  // Enabled if an assignment from the given type would require the
+  // source object to remain alive for the life of the element.
+  //
+  // TODO(b/402804213): Remove these traits and simplify the overloads whenever
+  // we have a better mechanism available to handle lifetime analysis.
+  template <class K, bool Value, typename = void>
+  using LifetimeBoundK = HasValue<
+      Value, std::conditional_t<policy_trait_element_is_owner<Policy>::value,
+                                std::false_type,
+                                type_traits_internal::IsLifetimeBoundAssignment<
+                                    typename Policy::key_type, K>>>;
+  template <class V, bool Value, typename = void>
+  using LifetimeBoundV =
+      HasValue<Value, type_traits_internal::IsLifetimeBoundAssignment<
+                          typename Policy::mapped_type, V>>;
+  template <class K, bool KValue, class V, bool VValue, typename... Dummy>
+  using LifetimeBoundKV =
+      absl::conjunction<LifetimeBoundK<K, KValue, absl::void_t<Dummy...>>,
+                        LifetimeBoundV<V, VValue>>;
+
  public:
   using key_type = typename Policy::key_type;
   using mapped_type = typename Policy::mapped_type;
@@ -71,87 +98,176 @@
   //   union { int n : 1; };
   //   flat_hash_map<int, int> m;
   //   m.insert_or_assign(n, n);
-  template <class K = key_type, class V = mapped_type, K* = nullptr,
-            V* = nullptr>
-  std::pair<iterator, bool> insert_or_assign(key_arg<K>&& k, V&& v)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(std::forward<K>(k), std::forward<V>(v));
-  }
+  //
+  // TODO(b/402804213): Remove these macros whenever we have a better mechanism
+  // available to handle lifetime analysis.
+#define ABSL_INTERNAL_X(Func, Callee, KQual, VQual, KValue, VValue, Tail, ...) \
+  template <                                                                   \
+      typename K = key_type, class V = mapped_type,                            \
+      ABSL_INTERNAL_IF_NOR(                                                    \
+          KValue, VValue,                                                      \
+          int = (EnableIf<LifetimeBoundKV<K, KValue, V, VValue,                \
+                                          IfRRef<int KQual>::AddPtr<K>,        \
+                                          IfRRef<int VQual>::AddPtr<V>>>()),   \
+          ABSL_INTERNAL_SINGLE_ARG(                                            \
+              int &...,                                                        \
+              decltype(EnableIf<LifetimeBoundKV<K, KValue, V, VValue>>()) =    \
+                  0))>                                                         \
+  decltype(auto) Func(__VA_ARGS__ key_arg<K> KQual k ABSL_INTERNAL_IF(         \
+                          KValue, ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)),  \
+                      V VQual v ABSL_INTERNAL_IF(                              \
+                          VValue, ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)))  \
+      ABSL_ATTRIBUTE_LIFETIME_BOUND {                                          \
+    return ABSL_INTERNAL_IF_OR(KValue, VValue, (this->template Func<K, V, 0>), \
+                               Callee)(std::forward<decltype(k)>(k),           \
+                                       std::forward<decltype(v)>(v)) Tail;     \
+  }                                                                            \
+  static_assert(true, "This is to force a semicolon.")
 
-  template <class K = key_type, class V = mapped_type, K* = nullptr>
-  std::pair<iterator, bool> insert_or_assign(key_arg<K>&& k, const V& v)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(std::forward<K>(k), v);
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  false, false, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  false, true, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  true, false, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  true, true, ABSL_INTERNAL_SINGLE_ARG());
 
-  template <class K = key_type, class V = mapped_type, V* = nullptr>
-  std::pair<iterator, bool> insert_or_assign(const key_arg<K>& k, V&& v)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(k, std::forward<V>(v));
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
+                  false, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
+                  true, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
+                  false, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
+                  true, ABSL_INTERNAL_SINGLE_ARG());
 
-  template <class K = key_type, class V = mapped_type>
-  std::pair<iterator, bool> insert_or_assign(const key_arg<K>& k, const V& v)
-      ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign_impl(k, v);
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
+                  false, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
+                  true, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
+                  false, ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
+                  true, ABSL_INTERNAL_SINGLE_ARG());
 
-  template <class K = key_type, class V = mapped_type, K* = nullptr,
-            V* = nullptr>
-  iterator insert_or_assign(const_iterator, key_arg<K>&& k,
-                            V&& v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign(std::forward<K>(k), std::forward<V>(v)).first;
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false, false,
+                  ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false, true,
+                  ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, false,
+                  ABSL_INTERNAL_SINGLE_ARG());
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, true,
+                  ABSL_INTERNAL_SINGLE_ARG());
 
-  template <class K = key_type, class V = mapped_type, K* = nullptr>
-  iterator insert_or_assign(const_iterator, key_arg<K>&& k,
-                            const V& v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign(std::forward<K>(k), v).first;
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  false, false, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  false, true, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  true, false, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
+                  true, true, .first, const_iterator ABSL_INTERNAL_COMMA);
 
-  template <class K = key_type, class V = mapped_type, V* = nullptr>
-  iterator insert_or_assign(const_iterator, const key_arg<K>& k,
-                            V&& v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign(k, std::forward<V>(v)).first;
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
+                  false, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
+                  true, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
+                  false, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
+                  true, .first, const_iterator ABSL_INTERNAL_COMMA);
 
-  template <class K = key_type, class V = mapped_type>
-  iterator insert_or_assign(const_iterator, const key_arg<K>& k,
-                            const V& v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert_or_assign(k, v).first;
-  }
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
+                  false, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
+                  true, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
+                  false, .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
+                  true, .first, const_iterator ABSL_INTERNAL_COMMA);
+
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false, false,
+                  .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false, true,
+                  .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, false,
+                  .first, const_iterator ABSL_INTERNAL_COMMA);
+  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, true,
+                  .first, const_iterator ABSL_INTERNAL_COMMA);
+#undef ABSL_INTERNAL_X
 
   // All `try_emplace()` overloads make the same guarantees regarding rvalue
   // arguments as `std::unordered_map::try_emplace()`, namely that these
   // functions will not move from rvalue arguments if insertions do not happen.
-  template <class K = key_type, class... Args,
+  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false, K *>>(),
+            class... Args,
             typename std::enable_if<
-                !std::is_convertible<K, const_iterator>::value, int>::type = 0,
-            K* = nullptr>
-  std::pair<iterator, bool> try_emplace(key_arg<K>&& k, Args&&... args)
+                !std::is_convertible<K, const_iterator>::value, int>::type = 0>
+  std::pair<iterator, bool> try_emplace(key_arg<K> &&k, Args &&...args)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...);
   }
 
   template <class K = key_type, class... Args,
+            EnableIf<LifetimeBoundK<K, true, K *>> = 0,
             typename std::enable_if<
                 !std::is_convertible<K, const_iterator>::value, int>::type = 0>
-  std::pair<iterator, bool> try_emplace(const key_arg<K>& k, Args&&... args)
+  std::pair<iterator, bool> try_emplace(
+      key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this),
+      Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template try_emplace<K, 0>(std::forward<K>(k),
+                                            std::forward<Args>(args)...);
+  }
+
+  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>(),
+            class... Args,
+            typename std::enable_if<
+                !std::is_convertible<K, const_iterator>::value, int>::type = 0>
+  std::pair<iterator, bool> try_emplace(const key_arg<K> &k, Args &&...args)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace_impl(k, std::forward<Args>(args)...);
   }
-
-  template <class K = key_type, class... Args, K* = nullptr>
-  iterator try_emplace(const_iterator, key_arg<K>&& k,
-                       Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return try_emplace(std::forward<K>(k), std::forward<Args>(args)...).first;
+  template <class K = key_type, class... Args,
+            EnableIf<LifetimeBoundK<K, true>> = 0,
+            typename std::enable_if<
+                !std::is_convertible<K, const_iterator>::value, int>::type = 0>
+  std::pair<iterator, bool> try_emplace(
+      const key_arg<K> &k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this),
+      Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template try_emplace<K, 0>(k, std::forward<Args>(args)...);
   }
 
-  template <class K = key_type, class... Args>
-  iterator try_emplace(const_iterator, const key_arg<K>& k,
-                       Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false, K *>>(),
+            class... Args>
+  iterator try_emplace(const_iterator, key_arg<K> &&k,
+                       Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return try_emplace(std::forward<K>(k), std::forward<Args>(args)...).first;
+  }
+  template <class K = key_type, class... Args,
+            EnableIf<LifetimeBoundK<K, true, K *>> = 0>
+  iterator try_emplace(const_iterator hint,
+                       key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this),
+                       Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template try_emplace<K, 0>(hint, std::forward<K>(k),
+                                            std::forward<Args>(args)...);
+  }
+
+  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>(),
+            class... Args>
+  iterator try_emplace(const_iterator, const key_arg<K> &k,
+                       Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return try_emplace(k, std::forward<Args>(args)...).first;
   }
+  template <class K = key_type, class... Args,
+            EnableIf<LifetimeBoundK<K, true>> = 0>
+  iterator try_emplace(const_iterator hint,
+                       const key_arg<K> &k
+                           ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this),
+                       Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template try_emplace<K, 0>(hint, std::forward<K>(k),
+                                            std::forward<Args>(args)...);
+  }
 
   template <class K = key_type, class P = Policy>
   MappedReference<P> at(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
@@ -174,8 +290,9 @@
     return Policy::value(&*it);
   }
 
-  template <class K = key_type, class P = Policy, K* = nullptr>
-  MappedReference<P> operator[](key_arg<K>&& key)
+  template <class K = key_type, class P = Policy,
+            int = EnableIf<LifetimeBoundK<K, false, K *>>()>
+  MappedReference<P> operator[](key_arg<K> &&key)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     // It is safe to use unchecked_deref here because try_emplace
     // will always return an iterator pointing to a valid item in the table,
@@ -183,15 +300,30 @@
     return Policy::value(
         &this->unchecked_deref(try_emplace(std::forward<K>(key)).first));
   }
+  template <class K = key_type, class P = Policy, int &...,
+            EnableIf<LifetimeBoundK<K, true, K *>> = 0>
+  MappedReference<P> operator[](
+      key_arg<K> &&key ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+      ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template operator[]<K, P, 0>(std::forward<K>(key));
+  }
 
-  template <class K = key_type, class P = Policy>
-  MappedReference<P> operator[](const key_arg<K>& key)
+  template <class K = key_type, class P = Policy,
+            int = EnableIf<LifetimeBoundK<K, false>>()>
+  MappedReference<P> operator[](const key_arg<K> &key)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     // It is safe to use unchecked_deref here because try_emplace
     // will always return an iterator pointing to a valid item in the table,
     // since it inserts if nothing is found for the given key.
     return Policy::value(&this->unchecked_deref(try_emplace(key).first));
   }
+  template <class K = key_type, class P = Policy, int &...,
+            EnableIf<LifetimeBoundK<K, true>> = 0>
+  MappedReference<P> operator[](
+      const key_arg<K> &key ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+      ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template operator[]<K, P, 0>(key);
+  }
 
  private:
   template <class K, class V>
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 41a480a..fdfb822 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -2495,15 +2495,15 @@
   //   flat_hash_map<std::string, int> m;
   //   m.insert(std::make_pair("abc", 42));
   template <class T,
-            std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
-                                 IsNotBitField<T>::value &&
-                                 !IsLifetimeBoundAssignmentFrom<T>::value,
-                             int> = 0>
+            int = std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
+                                       IsNotBitField<T>::value &&
+                                       !IsLifetimeBoundAssignmentFrom<T>::value,
+                                   int>()>
   std::pair<iterator, bool> insert(T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return emplace(std::forward<T>(value));
   }
 
-  template <class T,
+  template <class T, int&...,
             std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
                                  IsNotBitField<T>::value &&
                                  IsLifetimeBoundAssignmentFrom<T>::value,
@@ -2511,7 +2511,7 @@
   std::pair<iterator, bool> insert(
       T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return emplace(std::forward<T>(value));
+    return this->template insert<T, 0>(std::forward<T>(value));
   }
 
   // This overload kicks in when the argument is a bitfield or an lvalue of
@@ -2525,22 +2525,22 @@
   //   const char* p = "hello";
   //   s.insert(p);
   //
-  template <class T, std::enable_if_t<
+  template <class T, int = std::enable_if_t<
                          IsDecomposableAndInsertable<const T&>::value &&
                              !IsLifetimeBoundAssignmentFrom<const T&>::value,
-                         int> = 0>
+                         int>()>
   std::pair<iterator, bool> insert(const T& value)
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return emplace(value);
   }
-  template <class T,
+  template <class T, int&...,
             std::enable_if_t<IsDecomposableAndInsertable<const T&>::value &&
                                  IsLifetimeBoundAssignmentFrom<const T&>::value,
                              int> = 0>
   std::pair<iterator, bool> insert(
       const T& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
       ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return emplace(value);
+    return this->template insert<T, 0>(value);
   }
 
   // This overload kicks in when the argument is an rvalue of init_type. Its
@@ -2567,21 +2567,22 @@
 #endif
 
   template <class T,
-            std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
-                                 IsNotBitField<T>::value &&
-                                 !IsLifetimeBoundAssignmentFrom<T>::value,
-                             int> = 0>
+            int = std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
+                                       IsNotBitField<T>::value &&
+                                       !IsLifetimeBoundAssignmentFrom<T>::value,
+                                   int>()>
   iterator insert(const_iterator, T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     return insert(std::forward<T>(value)).first;
   }
-  template <class T,
+  template <class T, int&...,
             std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
                                  IsNotBitField<T>::value &&
                                  IsLifetimeBoundAssignmentFrom<T>::value,
                              int> = 0>
-  iterator insert(const_iterator, T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(
-                                      this)) ABSL_ATTRIBUTE_LIFETIME_BOUND {
-    return insert(std::forward<T>(value)).first;
+  iterator insert(const_iterator hint,
+                  T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+      ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    return this->template insert<T, 0>(hint, std::forward<T>(value));
   }
 
   template <class T, std::enable_if_t<