Propagate errors from `clang::tooling::applyAllReplacements`.

Chromium builds LLVM+Clang in Release+Asserts mode, which (before this
CL) would end up complaining about unchecked `llvm::Expected` from
`clang::tooling::applyAllReplacements`.

PiperOrigin-RevId: 452551782
diff --git a/rs_bindings_from_cc/BUILD b/rs_bindings_from_cc/BUILD
index 25abb41..c22994a 100644
--- a/rs_bindings_from_cc/BUILD
+++ b/rs_bindings_from_cc/BUILD
@@ -91,6 +91,7 @@
         ":ir_from_cc",
         ":src_code_gen",
         "//common:status_macros",
+        "@absl//absl/status:statusor",
     ],
 )
 
@@ -352,6 +353,8 @@
         ":cc_ir",
         ":src_code_gen_impl",  # buildcleaner: keep
         "//common:cc_ffi_types",
+        "//common:status_macros",
+        "@absl//absl/status:statusor",
         "@absl//absl/strings",
         "@llvm-project//clang:format",
         "@llvm-project//llvm:Support",
diff --git a/rs_bindings_from_cc/generate_bindings_and_metadata.cc b/rs_bindings_from_cc/generate_bindings_and_metadata.cc
index bf07451..6a2a9c4 100644
--- a/rs_bindings_from_cc/generate_bindings_and_metadata.cc
+++ b/rs_bindings_from_cc/generate_bindings_and_metadata.cc
@@ -29,9 +29,11 @@
           /* virtual_headers_contents= */ {}, cmdline.headers_to_targets(),
           clang_args_view, requested_instantiations));
 
-  crubit::Bindings bindings = crubit::GenerateBindings(
-      ir, cmdline.crubit_support_path(), cmdline.rustfmt_exe_path(),
-      cmdline.rustfmt_config_path());
+  CRUBIT_ASSIGN_OR_RETURN(
+      crubit::Bindings bindings,
+      crubit::GenerateBindings(ir, cmdline.crubit_support_path(),
+                               cmdline.rustfmt_exe_path(),
+                               cmdline.rustfmt_config_path()));
 
   return BindingsAndMetadata{
       .ir = ir,
diff --git a/rs_bindings_from_cc/generate_bindings_and_metadata.h b/rs_bindings_from_cc/generate_bindings_and_metadata.h
index 275e9d1..eceeec9 100644
--- a/rs_bindings_from_cc/generate_bindings_and_metadata.h
+++ b/rs_bindings_from_cc/generate_bindings_and_metadata.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/status/statusor.h"
 #include "rs_bindings_from_cc/cmdline.h"
 #include "rs_bindings_from_cc/ir.h"
 
diff --git a/rs_bindings_from_cc/src_code_gen.cc b/rs_bindings_from_cc/src_code_gen.cc
index e32c3a6..ba2f07f 100644
--- a/rs_bindings_from_cc/src_code_gen.cc
+++ b/rs_bindings_from_cc/src_code_gen.cc
@@ -7,8 +7,10 @@
 #include <string>
 
 #include "common/ffi_types.h"
+#include "common/status_macros.h"
 #include "rs_bindings_from_cc/ir.h"
 #include "clang/Format/Format.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/JSON.h"
 
@@ -27,7 +29,8 @@
                                             FfiU8Slice rustfmt_config_path);
 
 // Creates `Bindings` instance from copied data from `ffi_bindings`.
-static Bindings MakeBindingsFromFfiBindings(const FfiBindings& ffi_bindings) {
+static absl::StatusOr<Bindings> MakeBindingsFromFfiBindings(
+    const FfiBindings& ffi_bindings) {
   Bindings bindings;
 
   const FfiU8SliceBox& rs_api = ffi_bindings.rs_api;
@@ -36,11 +39,17 @@
   bindings.rs_api = std::string(rs_api.ptr, rs_api.size);
 
   std::string impl{rs_api_impl.ptr, rs_api_impl.size};
-  bindings.rs_api_impl = *clang::tooling::applyAllReplacements(
-      impl,
-      clang::format::reformat(
-          clang::format::getGoogleStyle(clang::format::FormatStyle::LK_Cpp),
-          impl, clang::tooling::Range(0, impl.size()), "<stdin>"));
+  llvm::Expected<std::string> maybe_formatted =
+      clang::tooling::applyAllReplacements(
+          impl,
+          clang::format::reformat(
+              clang::format::getGoogleStyle(clang::format::FormatStyle::LK_Cpp),
+              impl, clang::tooling::Range(0, impl.size()), "<stdin>"));
+  if (llvm::Error error = maybe_formatted.takeError()) {
+    return absl::InternalError(absl::StrCat("Failed to format rs_api_impl: ",
+                                            toString(std::move(error))));
+  }
+  bindings.rs_api_impl = *maybe_formatted;
 
   return bindings;
 }
@@ -51,15 +60,16 @@
   FreeFfiU8SliceBox(ffi_bindings.rs_api_impl);
 }
 
-Bindings GenerateBindings(const IR& ir, absl::string_view crubit_support_path,
-                          absl::string_view rustfmt_exe_path,
-                          absl::string_view rustfmt_config_path) {
+absl::StatusOr<Bindings> GenerateBindings(
+    const IR& ir, absl::string_view crubit_support_path,
+    absl::string_view rustfmt_exe_path, absl::string_view rustfmt_config_path) {
   std::string json = llvm::formatv("{0}", ir.ToJson());
 
   FfiBindings ffi_bindings = GenerateBindingsImpl(
       MakeFfiU8Slice(json), MakeFfiU8Slice(crubit_support_path),
       MakeFfiU8Slice(rustfmt_exe_path), MakeFfiU8Slice(rustfmt_config_path));
-  Bindings bindings = MakeBindingsFromFfiBindings(ffi_bindings);
+  CRUBIT_ASSIGN_OR_RETURN(Bindings bindings,
+                          MakeBindingsFromFfiBindings(ffi_bindings));
   FreeFfiBindings(ffi_bindings);
   return bindings;
 }
diff --git a/rs_bindings_from_cc/src_code_gen.h b/rs_bindings_from_cc/src_code_gen.h
index d59e2e9..6382eea 100644
--- a/rs_bindings_from_cc/src_code_gen.h
+++ b/rs_bindings_from_cc/src_code_gen.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "absl/status/statusor.h"
 #include "absl/strings/string_view.h"
 #include "rs_bindings_from_cc/ir.h"
 
@@ -21,9 +22,9 @@
 };
 
 // Generates bindings from the given `IR`.
-Bindings GenerateBindings(const IR& ir, absl::string_view crubit_support_path,
-                          absl::string_view rustfmt_exe_path,
-                          absl::string_view rustfmt_config_path);
+absl::StatusOr<Bindings> GenerateBindings(
+    const IR& ir, absl::string_view crubit_support_path,
+    absl::string_view rustfmt_exe_path, absl::string_view rustfmt_config_path);
 
 }  // namespace crubit