Fix handling of `const SomeStruct&` when generating thunk impls.

Before this CL, `format_cc_type` would error out when trying to format a const-ref:

    panicked at 'called `Result::unwrap()` on an `Err` value: Type not
    yet supported: CcType { name: Some("&"), is_const: false, type_args:
    [CcType { name: None, is_const: true, type_args: [], decl_id:
    Some(DeclId(95208605585584)) }], decl_id: None }',

Additionally, the `const` qualifier could be lost.

PiperOrigin-RevId: 419833272
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 64bbb79..4e05033 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -684,6 +684,13 @@
                 let nested_type = format_cc_type(&ty.type_args[0], ir)?;
                 Ok(quote! {#nested_type * #const_fragment})
             }
+            "&" => {
+                if ty.type_args.len() != 1 {
+                    bail!("Invalid reference type (need exactly 1 type argument): {:?}", ty);
+                }
+                let nested_type = format_cc_type(&ty.type_args[0], ir)?;
+                Ok(quote! {#nested_type &})
+            }
             ident => {
                 if !ty.type_args.is_empty() {
                     bail!("Type not yet supported: {:?}", ty);
@@ -700,7 +707,7 @@
                 .identifier
                 .as_str(),
         );
-        Ok(quote! {#ident})
+        Ok(quote! {#const_fragment #ident})
     }
 }
 
@@ -1018,6 +1025,36 @@
     }
 
     #[test]
+    fn test_ref_to_struct_in_thunk_impls() -> Result<()> {
+        let ir = ir_from_cc("struct S{}; inline void foo(S& s) {} ")?;
+        let rs_api_impl = generate_rs_api_impl(&ir)?;
+        assert_cc_matches!(
+            rs_api_impl,
+            quote! {
+                extern "C" void __rust_thunk___Z3fooR1S(S& s) {
+                    foo(s);
+                }
+            }
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_const_ref_to_struct_in_thunk_impls() -> Result<()> {
+        let ir = ir_from_cc("struct S{}; inline void foo(const S& s) {} ")?;
+        let rs_api_impl = generate_rs_api_impl(&ir)?;
+        assert_cc_matches!(
+            rs_api_impl,
+            quote! {
+                extern "C" void __rust_thunk___Z3fooRK1S(const S& s) {
+                    foo(s);
+                }
+            }
+        );
+        Ok(())
+    }
+
+    #[test]
     fn test_record_static_methods_qualify_call_in_thunk() -> Result<()> {
         let ir = ir_from_cc(&tokens_to_string(quote! {
             struct SomeStruct {
diff --git a/rs_bindings_from_cc/test/function/inline/hello_world.h b/rs_bindings_from_cc/test/function/inline/hello_world.h
index 84e7c07..e3bdd63 100644
--- a/rs_bindings_from_cc/test/function/inline/hello_world.h
+++ b/rs_bindings_from_cc/test/function/inline/hello_world.h
@@ -7,4 +7,11 @@
 
 inline int hello_world_inline() { return 42; }
 
+// This testcase helps verify that thunks correctly work with const-ref
+// parameters. Using an 'inline' method forces generation of a C++ thunk.
+struct SomeStruct {
+  int int_field;
+};
+inline int take_struct_by_const_ref(const SomeStruct& s) { return s.int_field; }
+
 #endif  // CRUBIT_RS_BINDINGS_FROM_CC_TEST_FUNCTION_INLINE_HELLO_WORLD_H_
diff --git a/rs_bindings_from_cc/test/function/inline/test.rs b/rs_bindings_from_cc/test/function/inline/test.rs
index 9eefb3a..7074d7b 100644
--- a/rs_bindings_from_cc/test/function/inline/test.rs
+++ b/rs_bindings_from_cc/test/function/inline/test.rs
@@ -4,10 +4,16 @@
 
 #[cfg(test)]
 mod tests {
-    use hello_world::hello_world_inline;
+    use hello_world::*;
 
     #[test]
     fn test_hello_world() {
         assert_eq!(hello_world_inline(), 42);
     }
+
+    #[test]
+    fn test_take_struct_by_const_ref() {
+        let s = SomeStruct { int_field: 789 };
+        assert_eq!(789, take_struct_by_const_ref(&s));
+    }
 }