Return `StatusOr` with type payload for failed type conversions

PiperOrigin-RevId: 397268707
diff --git a/rs_bindings_from_cc/ast_visitor.cc b/rs_bindings_from_cc/ast_visitor.cc
index 521aa53..f4d5a26 100644
--- a/rs_bindings_from_cc/ast_visitor.cc
+++ b/rs_bindings_from_cc/ast_visitor.cc
@@ -23,6 +23,9 @@
 
 namespace rs_bindings_from_cc {
 
+constexpr std::string_view kTypeStatusPayloadUrl =
+    "type.googleapis.com/devtools.rust.cc_interop.rs_binding_from_cc.type";
+
 bool AstVisitor::TraverseDecl(clang::Decl* decl) {
   if (seen_decls_.insert(decl->getCanonicalDecl()).second) {
     return Base::TraverseDecl(decl);
@@ -46,7 +49,7 @@
   for (const clang::ParmVarDecl* param : function_decl->parameters()) {
     auto param_type =
         ConvertType(param->getType(), function_decl->getASTContext());
-    if (!param_type.has_value()) {
+    if (!param_type.ok()) {
       // TODO(b/200239975):  Add diagnostics for declarations we can't import
       return true;
     }
@@ -55,7 +58,7 @@
 
   auto return_type = ConvertType(function_decl->getReturnType(),
                                  function_decl->getASTContext());
-  if (!return_type.has_value()) {
+  if (!return_type.ok()) {
     return true;
   }
   ir_.functions.push_back(Func{
@@ -96,7 +99,7 @@
   }
   for (const clang::FieldDecl* field_decl : record_decl->fields()) {
     auto type = ConvertType(field_decl->getType(), field_decl->getASTContext());
-    if (!type.has_value()) {
+    if (!type.ok()) {
       // TODO(b/200239975):  Add diagnostics for declarations we can't import
       return true;
     }
@@ -112,12 +115,14 @@
   return true;
 }
 
-std::optional<Type> AstVisitor::ConvertType(
+absl::StatusOr<Type> AstVisitor::ConvertType(
     clang::QualType qual_type, const clang::ASTContext& ctx) const {
+  std::string type_string = qual_type.getAsString();
+
   if (const clang::PointerType* pointer_type =
           qual_type->getAs<clang::PointerType>()) {
     auto pointee_type = ConvertType(pointer_type->getPointeeType(), ctx);
-    if (pointee_type.has_value()) {
+    if (pointee_type.ok()) {
       return Type::PointerTo(*pointee_type);
     }
   } else if (const clang::BuiltinType* builtin_type =
@@ -128,14 +133,17 @@
         return Type{
             absl::Substitute("$0$1",
                              builtin_type->isSignedInteger() ? 'i' : 'u', size),
-            qual_type.getAsString()};
+            type_string};
       }
     }
     if (builtin_type->isVoidType()) {
       return Type::Void();
     }
   }
-  return std::nullopt;
+  absl::Status error = absl::UnimplementedError(
+      absl::Substitute("Unsupported type '$0'", type_string));
+  error.SetPayload(kTypeStatusPayloadUrl, absl::Cord(type_string));
+  return error;
 }
 
 std::string AstVisitor::GetMangledName(