Implement the "definition" half of forward declarations / incomplete types.

This allows Rust code to forward-declare a C++ type, but we don't yet map forward declarations in C++ to forward declarations in Rust.

Note also that this doesn't test support for `!Unpin` types, as I encountered some quirks along the way -- might need a couple more impls to make this work, will investigate.

PiperOrigin-RevId: 440987359
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 513824e..62f0cc3 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -987,6 +987,13 @@
         quote! {}
     };
 
+    // TODO(b/227442773): After namespace support is added, use the fully-namespaced
+    // name.
+    let incomplete_symbol = &record.cc_name;
+    let incomplete_definition = quote! {
+        forward_declare::unsafe_define!(forward_declare::symbol!(#incomplete_symbol), #ident);
+    };
+
     let empty_struct_placeholder_field =
         if record.fields.is_empty() && record.base_size.unwrap_or(0) == 0 {
             quote! {
@@ -1034,6 +1041,8 @@
             #empty_struct_placeholder_field
         }
 
+        #incomplete_definition
+
         #no_unique_address_accessors
 
         #base_class_into
@@ -3048,7 +3057,10 @@
                     field2: [rust_std::mem::MaybeUninit<u8>; 2],
                     pub z: i16,
                 }
-
+            });
+        assert_rs_matches!(
+            rs_api,
+            quote! {
                 impl Struct {
                     pub fn field1(&self) -> &Field1 {
                         unsafe {&* (&self.field1 as *const _ as *const Field1)}