Allow function pointers with references inside the function signature.

Without this change, because we change the reference to a pointer, the type doesn't line up:

```
error: cannot initialize return object of type 'crubit::t
ype_identity_t<int *(const int *, int *)> *' (aka 'int *(*)(const int *, int *)') with an rvalue of type 'int &(*)(const int &, int *)': type mismatch at 1st parameter
('const int *' vs 'const int &')
```

I was worried this would mean we'd have trouble with `-Wreturn-type-c-linkage`, but surprisingly, it works fine:

https://godbolt.org/z/njabjEfTK

(As you can see, and as the name implies, it also works fine with reference parameters, but presumably there's another warning that fails there.)

I didn't add any other tests because really "does it compile?" is the main thing. This failed before, succeeds now.

PiperOrigin-RevId: 478958712
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 91f25f6..1a9c82e 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -3103,6 +3103,13 @@
 }
 
 fn format_cc_type(ty: &ir::CcType, ir: &IR) -> Result<TokenStream> {
+    // Formatting *both* pointers *and* references as pointers, because:
+    // - Pointers and references have the same representation in the ABI.
+    // - Clang's `-Wreturn-type-c-linkage` warns when using references in C++
+    //   function thunks declared as `extern "C"` (see b/238681766).
+    format_cc_type_inner(ty, ir, /* references_ok= */ false)
+}
+fn format_cc_type_inner(ty: &ir::CcType, ir: &IR, references_ok: bool) -> Result<TokenStream> {
     let const_fragment = if ty.is_const {
         quote! {const}
     } else {
@@ -3110,16 +3117,21 @@
     };
     if let Some(ref name) = ty.name {
         match name.as_str() {
-            // Formatting *both* pointers *and* references as pointers, because:
-            // - Pointers and references have the same representation in the ABI.
-            // - Clang's `-Wreturn-type-c-linkage` warns when using references in C++ function
-            //   thunks declared as `extern "C"` (see b/238681766).
-            "*" | "&" | "&&" => {
+            mut name @ ("*" | "&" | "&&") => {
                 if ty.type_args.len() != 1 {
                     bail!("Invalid pointer type (need exactly 1 type argument): {:?}", ty);
                 }
-                let nested_type = format_cc_type(&ty.type_args[0], ir)?;
-                Ok(quote! {#nested_type * #const_fragment})
+                let nested_type = format_cc_type_inner(&ty.type_args[0], ir, references_ok)?;
+                if !references_ok {
+                    name = "*";
+                }
+                let ptr = match name {
+                    "*" => quote! {*},
+                    "&" => quote! {&},
+                    "&&" => quote! {&&},
+                    _ => unreachable!(),
+                };
+                Ok(quote! {#nested_type #ptr #const_fragment})
             }
             cc_type_name => match cc_type_name.strip_prefix("#funcValue ") {
                 None => {
@@ -3132,10 +3144,14 @@
                 Some(abi) => match ty.type_args.split_last() {
                     None => bail!("funcValue type without a return type: {:?}", ty),
                     Some((ret_type, param_types)) => {
-                        let ret_type = format_cc_type(ret_type, ir)?;
+                        // Function pointer types don't ignore references, but luckily,
+                        // `-Wreturn-type-c-linkage` does. So we can just re-enable references now
+                        // so that the function type is exactly correct.
+                        let ret_type =
+                            format_cc_type_inner(ret_type, ir, /* references_ok= */ true)?;
                         let param_types = param_types
                             .iter()
-                            .map(|t| format_cc_type(t, ir))
+                            .map(|t| format_cc_type_inner(t, ir, /* references_ok= */ true))
                             .collect::<Result<Vec<_>>>()?;
                         let attr = format_cc_call_conv_as_clang_attribute(abi)?;
                         // `type_identity_t` is used below to avoid having to