Refactor `run_compiler` into a method of `CompilerCallbacks`.

This CL also renames `callbacks::CompilerCallbacks` into
`bindings_driver::RunCompiler` which better reflects what this type does
(and the naming and API shape nicely parallels that of
`rustc_driver::RunCompiler`).

PiperOrigin-RevId: 476371475
diff --git a/cc_bindings_from_rs/main.rs b/cc_bindings_from_rs/main.rs
index d297f12..cc2d36e 100644
--- a/cc_bindings_from_rs/main.rs
+++ b/cc_bindings_from_rs/main.rs
@@ -24,7 +24,7 @@
 use cmdline::Cmdline;
 use itertools::Itertools;
 
-mod bindings_generation {
+mod bindings_main {
 
     use anyhow::Context;
     use rustc_middle::ty::TyCtxt;
@@ -53,8 +53,9 @@
 
 /// Glue that enables the top-level `main() -> anyhow::Result<()>` to call into
 /// `fn main(cmdline: &Cmdline, tcx: TyCtxt) -> anyhow::Result<()>` in the
-/// `bindings_generation` module.
-mod callbacks {
+/// `bindings_main` module.  This mostly wraps and simplifies a subset of APIs
+/// from the `rustc_driver` module.
+mod bindings_driver {
 
     use rustc_interface::interface::Compiler;
     use rustc_interface::Queries;
@@ -62,38 +63,74 @@
     use crate::cmdline::Cmdline;
     use crate::lib::enter_tcx;
 
-    /// When passed to `rustc_driver::RunCompiler::run`, the `CompilerCallbacks`
-    /// below will wait until Rust compiler parsing and analysis are done,
-    /// and then will invoke `bindings_generation::main` and stash/expose
-    /// its result via `CompilerCallbacks::into_result`.
-    pub struct CompilerCallbacks<'a> {
+    /// Wrapper around `rustc_driver::RunCompiler` that exposes a simplified API
+    /// (e.g. doesn't take arbitrary `Callbacks` but always calls into
+    /// `bindings_main::main`).
+    pub struct RunCompiler<'a> {
         cmdline: &'a Cmdline,
-        result: Option<anyhow::Result<()>>,
+        bindings_main_result: Option<anyhow::Result<()>>,
     }
 
-    impl<'a> CompilerCallbacks<'a> {
+    impl<'a> RunCompiler<'a> {
+        /// Creates new Rust compiler runner that will
+        /// - pass `cmdline.rustc_args()` to the Rust compiler
+        /// - pass `cmdline` to `bindings_main::main` (in addition to passing
+        ///   `TyCtxt` - see the doc comment of `RunCompiler::run` below).
         pub fn new(cmdline: &'a Cmdline) -> Self {
-            Self { cmdline, result: None }
+            Self { cmdline, bindings_main_result: None }
         }
 
-        pub fn into_result(self) -> anyhow::Result<()> {
-            assert!(
-                self.result.is_some(),
-                "CompilerCallbacks::run_main should have been called by now"
-            );
-            self.result.unwrap()
+        /// Runs Rust compiler and then passes the `TyCtxt` of the
+        /// parsed+analyzed Rust crate into `bindings_main::main`.
+        /// Returns the combined results from Rust compiler *and*
+        /// `bindings_main::main`.
+        pub fn run(mut self) -> anyhow::Result<()> {
+            // Rust compiler unwinds with a special sentinel value to abort compilation on
+            // fatal errors. We use `catch_fatal_errors` to 1) catch such panics and
+            // translate them into a Result, and 2) resume and propagate other panics.
+            let rustc_result = rustc_driver::catch_fatal_errors(|| {
+                rustc_driver::RunCompiler::new(self.cmdline.rustc_args(), &mut self).run()
+            });
+
+            // Flatten `Result<Result<T, ...>>` into `Result<T, ...>` (i.e. get the Result
+            // from `RunCompiler::run` rather than the Result from
+            // `catch_fatal_errors`).
+            let rustc_result = rustc_result.and_then(|result| result);
+
+            // Translate `rustc_interface::interface::Result` into `anyhow::Result`.  (Can't
+            // use `?` because the trait `std::error::Error` is not implemented for
+            // `ErrorGuaranteed` which is required by the impl of
+            // `From<ErrorGuaranteed>` for `anyhow::Error`.)
+            let rustc_result = rustc_result.map_err(|_err| {
+                // We can ignore `_err` because it has no payload / because this type has only
+                // one valid/possible value.
+                anyhow::format_err!("Errors reported by Rust compiler.")
+            });
+
+            // Return either `rustc_result` or `self.bindings_main_result`.
+            rustc_result.and_then(|()| {
+                assert!(
+                    self.bindings_main_result.is_some(),
+                    "RunCompiler::run_main should have been called by now"
+                );
+                self.bindings_main_result.unwrap()
+            })
         }
     }
 
-    impl rustc_driver::Callbacks for CompilerCallbacks<'_> {
+    impl rustc_driver::Callbacks for RunCompiler<'_> {
         fn after_analysis<'tcx>(
             &mut self,
             _compiler: &Compiler,
             queries: &'tcx Queries<'tcx>,
         ) -> rustc_driver::Compilation {
             let rustc_result = enter_tcx(queries, |tcx| {
-                assert!(self.result.is_none(), "after_analysis should only run once");
-                self.result = Some(crate::bindings_generation::main(self.cmdline, tcx));
+                assert!(
+                    self.bindings_main_result.is_none(),
+                    "after_analysis should only run once"
+                );
+                self.bindings_main_result =
+                    Some(crate::bindings_main::main(self.cmdline, tcx))
             });
 
             // `expect`ing no errors in `rustc_result`, because `after_analysis` is only
@@ -107,38 +144,9 @@
     }
 }
 
-/// Wrapper around `rustc_driver::RunCompiler::run` that returns
-/// `anyhow::Result<()>` instead of either returning
-/// `rustc_interface::interface::Result<()>` or panicking with a special
-/// sentinel value.
-fn run_compiler<T>(rustc_args: &[String], callbacks: &mut T) -> anyhow::Result<()>
-where
-    T: rustc_driver::Callbacks + Send,
-{
-    // Rust compiler unwinds with a special sentinel value to abort compilation on
-    // fatal errors. We use `catch_fatal_errors` to 1) catch such panics and
-    // translate them into a Result, and 2) resume and propagate other panics.
-    let result = rustc_driver::catch_fatal_errors(|| {
-        rustc_driver::RunCompiler::new(rustc_args, callbacks).run()
-    });
-
-    // Flatten `Result<Result<T, ...>>` into `Result<T, ...>`.
-    let result = result.and_then(|result| result);
-
-    // Translate `rustc_interface::interface::Result` into `anyhow::Result`.  (Can't
-    // use `?` because the trait `std::error::Error` is not implemented for
-    // `ErrorGuaranteed` which is required by the impl of
-    // `From<ErrorGuaranteed>` for `anyhow::Error`.)
-    result.map_err(|_err| {
-        // We can ignore `_err` because it has no payload / because this type has only
-        // one valid/possible value.
-        anyhow::format_err!("Errors reported by Rust compiler.")
-    })
-}
-
 // TODO(lukasza): Add end-to-end tests that verify that the exit code is
 // non-zero when:
-// * input contains syntax errors - test coverage for `run_compiler`.
+// * input contains syntax errors - test coverage for `RunCompiler::run`.
 // * mandatory parameters (e.g. `--h_out`) are missing - test coverage for how
 //   `main` calls `Cmdline::new`.
 // * `--h_out` cannot be written to (in this case, the error message should
@@ -160,8 +168,7 @@
         Cmdline::new(&args)?
     };
 
-    // Invoke the Rust compiler with Crubit-specific `callbacks`.
-    let mut callbacks = callbacks::CompilerCallbacks::new(&cmdline);
-    run_compiler(cmdline.rustc_args(), &mut callbacks)?;
-    callbacks.into_result()
+    // Invoke the Rust compiler and call `bindings_main::main` after parsing and
+    // analysis are done.
+    bindings_driver::RunCompiler::new(&cmdline).run()
 }