[rs_bindings_from_cc] Avoid copying `ValueLifetimes` when converting types.

Now that we're using `FunctionLifetimes` as intended, `ConvertQualType()` no
longer needs to modify the `lifetimes` passed in to it.

PiperOrigin-RevId: 546947935
Change-Id: I5ed258c331cc4dc9af56318973075dabaabd782b
diff --git a/rs_bindings_from_cc/BUILD b/rs_bindings_from_cc/BUILD
index 23545e2..e4f8510 100644
--- a/rs_bindings_from_cc/BUILD
+++ b/rs_bindings_from_cc/BUILD
@@ -210,6 +210,7 @@
         "cc_ir",
         ":bazel_types",
         "//lifetime_annotations",
+        "//lifetime_annotations:type_lifetimes",
         "@absl//absl/container:flat_hash_map",
         "@absl//absl/log:check",
         "@absl//absl/status:statusor",
diff --git a/rs_bindings_from_cc/decl_importer.h b/rs_bindings_from_cc/decl_importer.h
index f221036..6c7e346 100644
--- a/rs_bindings_from_cc/decl_importer.h
+++ b/rs_bindings_from_cc/decl_importer.h
@@ -15,6 +15,7 @@
 #include "absl/log/check.h"
 #include "absl/status/statusor.h"
 #include "lifetime_annotations/lifetime_annotations.h"
+#include "lifetime_annotations/type_lifetimes.h"
 #include "rs_bindings_from_cc/bazel_types.h"
 #include "rs_bindings_from_cc/ir.h"
 #include "clang/AST/Type.h"
@@ -139,7 +140,8 @@
       clang::SourceLocation loc) const = 0;
 
   // Converts the Clang type `qual_type` into an equivalent `MappedType`.
-  // Lifetimes for the type can optionally be specified using `lifetimes`.
+  // Lifetimes for the type can optionally be specified using `lifetimes` (pass
+  // null otherwise).
   // If `qual_type` is a pointer type, `nullable` specifies whether the
   // pointer can be null.
   // TODO(b/209390498): Currently, we're able to specify nullability only for
@@ -150,7 +152,7 @@
   // nullability annotations.
   virtual absl::StatusOr<MappedType> ConvertQualType(
       clang::QualType qual_type,
-      std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+      const clang::tidy::lifetimes::ValueLifetimes* lifetimes,
       std::optional<clang::RefQualifierKind> ref_qualifier_kind,
       bool nullable = true) = 0;
 
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index 259c6a0..92feccb 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -774,14 +774,13 @@
 
 absl::StatusOr<MappedType> Importer::ConvertType(
     const clang::Type* type,
-    std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+    const clang::tidy::lifetimes::ValueLifetimes* lifetimes,
     std::optional<clang::RefQualifierKind> ref_qualifier_kind, bool nullable) {
   // Qualifiers are handled separately in ConvertQualType().
   std::string type_string = clang::QualType(type, 0).getAsString();
 
-  assert(!lifetimes.has_value() ||
-         IsSameCanonicalUnqualifiedType(lifetimes->Type(),
-                                        clang::QualType(type, 0)));
+  assert(!lifetimes || IsSameCanonicalUnqualifiedType(
+                           lifetimes->Type(), clang::QualType(type, 0)));
 
   if (auto override_type = GetTypeMapOverride(*type);
       override_type.has_value()) {
@@ -790,10 +789,11 @@
              type->isRValueReferenceType()) {
     clang::QualType pointee_type = type->getPointeeType();
     std::optional<LifetimeId> lifetime;
-    if (lifetimes.has_value()) {
+    const clang::tidy::lifetimes::ValueLifetimes* pointee_lifetimes = nullptr;
+    if (lifetimes) {
       lifetime =
           LifetimeId(lifetimes->GetPointeeLifetimes().GetLifetime().Id());
-      lifetimes = lifetimes->GetPointeeLifetimes().GetValueLifetimes();
+      pointee_lifetimes = &lifetimes->GetPointeeLifetimes().GetValueLifetimes();
     }
     if (const auto* func_type =
             pointee_type->getAs<clang::FunctionProtoType>()) {
@@ -808,9 +808,11 @@
       CRUBIT_ASSIGN_OR_RETURN(
           absl::string_view rs_abi,
           ConvertCcCallConvIntoRsAbi(func_type->getCallConv()));
-      std::optional<clang::tidy::lifetimes::ValueLifetimes> return_lifetimes;
-      if (lifetimes.has_value())
-        return_lifetimes = lifetimes->GetFuncLifetimes().GetReturnLifetimes();
+      const clang::tidy::lifetimes::ValueLifetimes* return_lifetimes = nullptr;
+      if (pointee_lifetimes) {
+        return_lifetimes =
+            &pointee_lifetimes->GetFuncLifetimes().GetReturnLifetimes();
+      }
       CRUBIT_ASSIGN_OR_RETURN(
           MappedType mapped_return_type,
           ConvertQualType(func_type->getReturnType(), return_lifetimes,
@@ -818,9 +820,11 @@
 
       std::vector<MappedType> mapped_param_types;
       for (unsigned i = 0; i < func_type->getNumParams(); ++i) {
-        std::optional<clang::tidy::lifetimes::ValueLifetimes> param_lifetimes;
-        if (lifetimes.has_value())
-          param_lifetimes = lifetimes->GetFuncLifetimes().GetParamLifetimes(i);
+        const clang::tidy::lifetimes::ValueLifetimes* param_lifetimes = nullptr;
+        if (pointee_lifetimes) {
+          param_lifetimes =
+              &pointee_lifetimes->GetFuncLifetimes().GetParamLifetimes(i);
+        }
         CRUBIT_ASSIGN_OR_RETURN(
             MappedType mapped_param_type,
             ConvertQualType(func_type->getParamType(i), param_lifetimes,
@@ -842,7 +846,7 @@
 
     CRUBIT_ASSIGN_OR_RETURN(
         MappedType mapped_pointee_type,
-        ConvertQualType(pointee_type, lifetimes, ref_qualifier_kind));
+        ConvertQualType(pointee_type, pointee_lifetimes, ref_qualifier_kind));
     if (type->isPointerType()) {
       return MappedType::PointerTo(std::move(mapped_pointee_type), lifetime,
                                    ref_qualifier_kind, nullable);
@@ -958,7 +962,7 @@
 
 absl::StatusOr<MappedType> Importer::ConvertQualType(
     clang::QualType qual_type,
-    std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+    const clang::tidy::lifetimes::ValueLifetimes* lifetimes,
     std::optional<clang::RefQualifierKind> ref_qualifier_kind, bool nullable) {
   qual_type = GetUnelaboratedType(std::move(qual_type), ctx_);
   std::string type_string = qual_type.getAsString();
diff --git a/rs_bindings_from_cc/importer.h b/rs_bindings_from_cc/importer.h
index 782212c..390c3fe 100644
--- a/rs_bindings_from_cc/importer.h
+++ b/rs_bindings_from_cc/importer.h
@@ -83,7 +83,7 @@
   std::string ConvertSourceLocation(clang::SourceLocation loc) const override;
   absl::StatusOr<MappedType> ConvertQualType(
       clang::QualType qual_type,
-      std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+      const clang::tidy::lifetimes::ValueLifetimes* lifetimes,
       std::optional<clang::RefQualifierKind> ref_qualifier_kind,
       bool nullable = true) override;
 
@@ -128,7 +128,7 @@
   // the `this` pointer.
   absl::StatusOr<MappedType> ConvertType(
       const clang::Type* type,
-      std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+      const clang::tidy::lifetimes::ValueLifetimes* lifetimes,
       std::optional<clang::RefQualifierKind> ref_qualifier_kind, bool nullable);
   absl::StatusOr<MappedType> ConvertTypeDecl(clang::NamedDecl* decl);
 
diff --git a/rs_bindings_from_cc/importers/BUILD b/rs_bindings_from_cc/importers/BUILD
index dbf0d79..e23c298 100644
--- a/rs_bindings_from_cc/importers/BUILD
+++ b/rs_bindings_from_cc/importers/BUILD
@@ -24,6 +24,7 @@
         "@absl//absl/log",
         "@absl//absl/log:check",
         "@absl//absl/log:die_if_null",
+        "//lifetime_annotations:type_lifetimes",
         "//rs_bindings_from_cc:ast_convert",
         "//rs_bindings_from_cc:bazel_types",
         "//rs_bindings_from_cc:decl_importer",
@@ -39,6 +40,7 @@
     srcs = ["enum.cc"],
     hdrs = ["enum.h"],
     deps = [
+        "//lifetime_annotations:type_lifetimes",
         "//rs_bindings_from_cc:decl_importer",
         "@llvm-project//clang:ast",
     ],
@@ -61,6 +63,7 @@
     deps = [
         "@absl//absl/strings",
         "//lifetime_annotations:lifetime_error",
+        "//lifetime_annotations:type_lifetimes",
         "//rs_bindings_from_cc:ast_util",
         "//rs_bindings_from_cc:decl_importer",
         "@llvm-project//clang:ast",
@@ -97,8 +100,8 @@
     hdrs = ["type_alias.h"],
     deps = [
         "@absl//absl/log:check",
+        "//lifetime_annotations:type_lifetimes",
         "//rs_bindings_from_cc:decl_importer",
-        "//rs_bindings_from_cc:type_map",
         "@llvm-project//clang:ast",
     ],
 )
diff --git a/rs_bindings_from_cc/importers/cxx_record.cc b/rs_bindings_from_cc/importers/cxx_record.cc
index d5b7b4d..98c9aa3 100644
--- a/rs_bindings_from_cc/importers/cxx_record.cc
+++ b/rs_bindings_from_cc/importers/cxx_record.cc
@@ -12,6 +12,7 @@
 #include "absl/log/check.h"
 #include "absl/log/die_if_null.h"
 #include "absl/log/log.h"
+#include "lifetime_annotations/type_lifetimes.h"
 #include "rs_bindings_from_cc/ast_convert.h"
 #include "rs_bindings_from_cc/bazel_types.h"
 #include "clang/AST/ASTContext.h"
@@ -375,7 +376,7 @@
       access = default_access;
     }
 
-    std::optional<clang::tidy::lifetimes::ValueLifetimes> no_lifetimes;
+    const clang::tidy::lifetimes::ValueLifetimes* no_lifetimes = nullptr;
     absl::StatusOr<MappedType> type;
     switch (access) {
       case clang::AS_public:
diff --git a/rs_bindings_from_cc/importers/enum.cc b/rs_bindings_from_cc/importers/enum.cc
index 4691268..ea006fb 100644
--- a/rs_bindings_from_cc/importers/enum.cc
+++ b/rs_bindings_from_cc/importers/enum.cc
@@ -4,6 +4,8 @@
 
 #include "rs_bindings_from_cc/importers/enum.h"
 
+#include "lifetime_annotations/type_lifetimes.h"
+
 namespace crubit {
 
 std::optional<IR::Item> EnumDeclImporter::Import(clang::EnumDecl* enum_decl) {
@@ -34,7 +36,7 @@
         enum_decl,
         "Forward declared enums without type specifiers are not supported");
   }
-  std::optional<clang::tidy::lifetimes::ValueLifetimes> no_lifetimes;
+  const clang::tidy::lifetimes::ValueLifetimes* no_lifetimes = nullptr;
   absl::StatusOr<MappedType> type =
       ictx_.ConvertQualType(cc_type, no_lifetimes, std::nullopt);
   if (!type.ok()) {
diff --git a/rs_bindings_from_cc/importers/function.cc b/rs_bindings_from_cc/importers/function.cc
index a39c5cf..56de6de 100644
--- a/rs_bindings_from_cc/importers/function.cc
+++ b/rs_bindings_from_cc/importers/function.cc
@@ -8,6 +8,7 @@
 
 #include "absl/strings/substitute.h"
 #include "lifetime_annotations/lifetime_error.h"
+#include "lifetime_annotations/type_lifetimes.h"
 #include "rs_bindings_from_cc/ast_util.h"
 #include "clang/AST/Type.h"
 #include "clang/Sema/Sema.h"
@@ -142,9 +143,9 @@
 
     // non-static member functions receive an implicit `this` parameter.
     if (method_decl->isInstance()) {
-      std::optional<clang::tidy::lifetimes::ValueLifetimes> this_lifetimes;
+      const clang::tidy::lifetimes::ValueLifetimes* this_lifetimes = nullptr;
       if (lifetimes) {
-        this_lifetimes = lifetimes->GetThisLifetimes();
+        this_lifetimes = &lifetimes->GetThisLifetimes();
       }
       auto param_type =
           ictx_.ConvertQualType(method_decl->getThisType(), this_lifetimes,
@@ -166,9 +167,9 @@
 
   for (unsigned i = 0; i < function_decl->getNumParams(); ++i) {
     const clang::ParmVarDecl* param = function_decl->getParamDecl(i);
-    std::optional<clang::tidy::lifetimes::ValueLifetimes> param_lifetimes;
+    const clang::tidy::lifetimes::ValueLifetimes* param_lifetimes = nullptr;
     if (lifetimes) {
-      param_lifetimes = lifetimes->GetParamLifetimes(i);
+      param_lifetimes = &lifetimes->GetParamLifetimes(i);
     }
     auto param_type =
         ictx_.ConvertQualType(param->getType(), param_lifetimes, std::nullopt);
@@ -191,9 +192,9 @@
     }
   }
 
-  std::optional<clang::tidy::lifetimes::ValueLifetimes> return_lifetimes;
+  const clang::tidy::lifetimes::ValueLifetimes* return_lifetimes = nullptr;
   if (lifetimes) {
-    return_lifetimes = lifetimes->GetReturnLifetimes();
+    return_lifetimes = &lifetimes->GetReturnLifetimes();
   }
 
   auto return_type = ictx_.ConvertQualType(function_decl->getReturnType(),
diff --git a/rs_bindings_from_cc/importers/type_alias.cc b/rs_bindings_from_cc/importers/type_alias.cc
index 8d50a90..ebfbde8 100644
--- a/rs_bindings_from_cc/importers/type_alias.cc
+++ b/rs_bindings_from_cc/importers/type_alias.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/log/check.h"
+#include "lifetime_annotations/type_lifetimes.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 
@@ -68,7 +69,7 @@
                            identifier.status().message()));
   }
 
-  std::optional<clang::tidy::lifetimes::ValueLifetimes> no_lifetimes;
+  clang::tidy::lifetimes::ValueLifetimes* no_lifetimes = nullptr;
   // TODO(mboehme): Once lifetime_annotations supports retrieving lifetimes in
   // type aliases, pass these to ConvertQualType().
   absl::StatusOr<MappedType> underlying_type =